diff --git a/.vscode/launch.json b/.vscode/launch.json index 6757ed47f6..4b563febde 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -25,4 +25,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container new file mode 100644 index 0000000000..fbf9ba8f4b --- /dev/null +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -0,0 +1,261 @@ +#!/bin/groovy +/* + * 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 + */ + +// Location of the executor node +def nodeExecutor = params.nodeExecutor + +// Tags to shorten pipeline duration +def doMandatoryTests = false +def doFullTestsuite = false + +pipeline { + agent { + label nodeExecutor + } + options { + disableConcurrentBuilds() + timestamps() + gitLabConnection('OAI GitLab') + ansiColor('xterm') + } + + stages { + stage ("Verify Parameters") { + steps { + script { + JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"' + JOB_TIMESTAMP = JOB_TIMESTAMP.trim() + + echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' + def allParametersPresent = true + + 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 + } + } + } + } + stage ("Verify Guidelines") { + steps { + echo "Git URL is ${GIT_URL}" + echo "GitLab Act is ${env.gitlabActionType}" + script { + if ("MERGE".equals(env.gitlabActionType)) { + // since a bit, in push events, gitlabUserEmail is not populated + gitCommitAuthorEmailAddr = env.gitlabUserEmail + echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}" + // GitLab-Jenkins plugin integration is lacking to perform the merge by itself + // Doing it manually --> it may have merge conflicts + sh "./ci-scripts/doGitLabMerge.sh --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}" + } else { + echo "Git Branch is ${GIT_BRANCH}" + echo "Git Commit is ${GIT_COMMIT}" + // since a bit, in push events, gitlabUserEmail is not populated + gitCommitAuthorEmailAddr = sh returnStdout: true, script: 'git log -n1 --pretty=format:%ae ${GIT_COMMIT}' + gitCommitAuthorEmailAddr = gitCommitAuthorEmailAddr.trim() + echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}" + sh "git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG" + } + } + } + post { + failure { + script { + def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Merge Conflicts -- Cannot perform CI" + addGitLabMRComment comment: message + currentBuild.result = 'FAILURE' + } + } + } + } + // Build Stages are Mandatory + // Later we will add a Ubuntu20 build + stage ("Image Building Processes") { + parallel { + stage ("Ubuntu18 Build") { + steps { + script { + triggerSlaveJob ('RAN-Ubuntu18-Image-Builder', 'Ubuntu18-Images-Build') + } + } + post { + always { + script { + finalizeSlaveJob('RAN-Ubuntu18-Image-Builder') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } + stage ("RHEL8 Build") { + steps { + script { + triggerSlaveJob ('RAN-RHEL8-Image-Builder', 'RHEL8-Images-Build') + } + } + post { + always { + script { + finalizeSlaveJob('RAN-RHEL8-Image-Builder') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } + } + } + } + post { + always { + script { + emailext attachmentsPattern: '*results*.html', + body: '''Hi, + +Here are attached HTML report files for $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS! + +Regards, +OAI CI Team''', + replyTo: 'no-reply@openairinterface.org', + subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!', + to: gitCommitAuthorEmailAddr + + if (fileExists('.git/CI_COMMIT_MSG')) { + sh "rm -f .git/CI_COMMIT_MSG" + } + } + } + success { + script { + def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")" + if ("MERGE".equals(env.gitlabActionType)) { + echo "This is a MERGE event" + addGitLabMRComment comment: message + } + } + } + failure { + script { + def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ")" + if ("MERGE".equals(env.gitlabActionType)) { + echo "This is a MERGE event" + addGitLabMRComment comment: message + } + } + } + } +} + +// ---- Slave Job functions + +def triggerSlaveJob (jobName, gitlabStatusName) { + // Workaround for the "cancelled" GitLab pipeline notification + // The slave job is triggered with the propagate false so the following commands are executed + // Its status is now PASS/SUCCESS from a stage pipeline point of view + // localStatus variable MUST be analyzed to properly assess the status + localStatus = build job: jobName, + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: "MERGE".equals(env.gitlabActionType)), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) + ], propagate: false + localResult = localStatus.getResult() + echo "${jobName} Slave Job status is ${localResult}" + gitlabCommitStatus(name: gitlabStatusName) { + if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) { + echo "${jobName} Slave Job is OK" + } else { + echo "${jobName} Slave Job is KO" + sh "ci-scripts/fail.sh" + } + } +} + +def triggerSlaveJobNoGitLab (jobName) { + // Workaround for the "cancelled" GitLab pipeline notification + // The slave job is triggered with the propagate false so the following commands are executed + // Its status is now PASS/SUCCESS from a stage pipeline point of view + // localStatus variable MUST be analyzed to properly assess the status + localStatus = build job: jobName, + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: "MERGE".equals(env.gitlabActionType)), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) + ], propagate: false + localResult = localStatus.getResult() + echo "${jobName} Slave Job status is ${localResult}" + if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) { + echo "${jobName} Slave Job is OK" + } else { + echo "${jobName} Slave Job is KO" + sh "ci-scripts/fail.sh" + } +} + +def finalizeSlaveJob(jobName) { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. The only drop-back is that we may retrieve the HTML report of a previous build + fileName = "test_results-${jobName}.html" + if (!fileExists(fileName)) { + copyArtifacts(projectName: jobName, + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists(fileName)) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' ${fileName}" + archiveArtifacts artifacts: fileName + } + } +} diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index ff661543c0..de49275b7e 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -196,16 +196,6 @@ pipeline { } } - 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) { @@ -251,7 +241,7 @@ pipeline { stage ("Analysis with cppcheck") { steps { gitlabCommitStatus(name: "Analysis with cppcheck") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } @@ -260,7 +250,7 @@ pipeline { stage ("Build basic simulator") { steps { gitlabCommitStatus(name: "Build basic-sim") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -269,7 +259,7 @@ pipeline { stage ("Build 5G gNB-USRP") { steps { gitlabCommitStatus(name: "Build gNB-USRP") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -278,25 +268,16 @@ pipeline { stage ("Build 5G NR-UE-USRP") { steps { gitlabCommitStatus(name: "Build nr-UE-USRP") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } } - stage ("Build eNB-USRP") { - steps { - gitlabCommitStatus(name: "Build eNB-USRP") { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } - } - } stage ("Build physical simulators") { steps { gitlabCommitStatus(name: "Build phy-sim") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -305,7 +286,7 @@ pipeline { stage ("Build eNB-ethernet") { steps { gitlabCommitStatus(name: "Build eNB-ethernet") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } @@ -316,7 +297,7 @@ pipeline { // This is typically the last one to finish. lock (vmResource) { gitlabCommitStatus(name: "Build UE-ethernet") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, 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" } } diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb-benetel b/ci-scripts/Jenkinsfile-tmp-multi-enb-benetel new file mode 100644 index 0000000000..8ac2e6adff --- /dev/null +++ b/ci-scripts/Jenkinsfile-tmp-multi-enb-benetel @@ -0,0 +1,293 @@ +#!/bin/groovy +/* + * 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 + */ + +// Template Jenkins Declarative Pipeline script to run Test w/ RF HW + +// Location of the python executor node shall be in the same subnet as the others servers +def pythonExecutor = params.pythonExecutor + +// Location of the test XML file to be run +def testXMLFile = params.pythonTestXmlFile +def mainPythonAllXmlFiles = "" +def buildStageStatus = true + +// Name of the test stage +def testStageName = params.pipelineTestStageName + +// Name of the phone resource +def ciSmartPhonesResource1 = params.SmartPhonesResource1 +def ciSmartPhonesResource2 = params.SmartPhonesResource2 + +// Global Parameters. Normally they should be populated when the master job +// triggers the slave job with parameters +def eNB_Repository +def eNB_Branch +def eNB_CommitID +def eNB_AllowMergeRequestProcess +def eNB_TargetBranch + +pipeline { + agent { + label pythonExecutor + } + options { + disableConcurrentBuilds() + ansiColor('xterm') + lock(extra: [[resource: ciSmartPhonesResource2]], resource: ciSmartPhonesResource1) + } + stages { + stage("Build Init") { + steps { + // update the build name and description + buildName "${params.eNB_MR}" + buildDescription "Branch : ${params.eNB_Branch}" + } + } + stage ("Verify Parameters") { + steps { + script { + echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' + def allParametersPresent = true + + // It is already to late to check it + if (params.pythonExecutor != null) { + echo "eNB CI executor node : ${pythonExecutor}" + } + // If not present picking a default Stage Name + if (params.pipelineTestStageName == null) { + // picking default + testStageName = 'Template Test Stage' + } + + if (params.SmartPhonesResource1 == null) { + allParametersPresent = false + } + if (params.SmartPhonesResource2 == null) { + allParametersPresent = false + } + // 1st eNB parameters + if (params.eNB_IPAddress == null) { + allParametersPresent = false + } + if (params.eNB_SourceCodePath == null) { + allParametersPresent = false + } + if (params.eNB_Credentials == null) { + allParametersPresent = false + } + // 2nd eNB parameters + if (params.eNB1_IPAddress == null) { + allParametersPresent = false + } + if (params.eNB1_SourceCodePath == null) { + allParametersPresent = false + } + if (params.eNB1_Credentials == null) { + allParametersPresent = false + } + // 3rd eNB parameters + if (params.eNB2_IPAddress == null) { + allParametersPresent = false + } + if (params.eNB2_SourceCodePath == null) { + allParametersPresent = false + } + if (params.eNB2_Credentials == null) { + allParametersPresent = false + } + // the following 4 parameters should be pushed by the master trigger + // if not present, take the job GIT variables (used for developing) + if (params.eNB_Repository == null) { + eNB_Repository = env.GIT_URL + } else { + eNB_Repository = params.eNB_Repository + } + echo "eNB_Repository : ${eNB_Repository}" + if (params.eNB_Branch == null) { + eNB_Branch = env.GIT_BRANCH + } else { + eNB_Branch = params.eNB_Branch + } + echo "eNB_Branch : ${eNB_Branch}" + if (params.eNB_CommitID == null) { + eNB_CommitID = env.GIT_COMMIT + } else { + eNB_CommitID = params.eNB_CommitID + } + echo "eNB_CommitID : ${eNB_CommitID}" + if (params.eNB_AllowMergeRequestProcess!= null) { + eNB_AllowMergeRequestProcess = params.eNB_AllowMergeRequestProcess + if (eNB_AllowMergeRequestProcess) { + if (params.eNB_TargetBranch != null) { + eNB_TargetBranch = params.eNB_TargetBranch + } else { + eNB_TargetBranch = 'develop' + } + echo "eNB_TargetBranch : ${eNB_TargetBranch}" + } + } + + if (params.EPC_IPAddress == null) { + allParametersPresent = false + } + if (params.EPC_Type == null) { + allParametersPresent = false + } + if (params.EPC_SourceCodePath == null) { + allParametersPresent = false + } + if (params.EPC_Credentials == null) { + allParametersPresent = false + } + + if (params.ADB_IPAddress == null) { + allParametersPresent = false + } + if (params.ADB_Credentials == null) { + allParametersPresent = false + } + + if (allParametersPresent) { + echo "All parameters are present" + if (eNB_AllowMergeRequestProcess) { + sh "git fetch" + sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" + } else { + sh "git fetch" + sh "git checkout -f ${eNB_CommitID}" + } + } else { + echo "Some parameters are missing" + sh "./ci-scripts/fail.sh" + } + } + } + } + stage ("Build and Test") { + steps { + script { + dir ('ci-scripts') { + echo "\u2705 \u001B[32m${testStageName}\u001B[0m" + // If not present picking a default XML file + if (params.pythonTestXmlFile == null) { + // picking default + testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' + echo "Test XML file(default): ${testXMLFile}" + mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " + } else { + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { + mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " + echo "Test XML file : ${xmlFile}" + } + } + } + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] + ]) { + sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { + try { + sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + } catch (Exception e) { + currentBuild.result = 'FAILURE' + buildStageStatus = false + } + } + } + sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" + } + } + } + } + } + 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 (eNB - Run)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m' + sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("enb.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "enb.log.${env.BUILD_ID}.zip" + } + if(fileExists("ci-scripts/test_results.html")) { + sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html" + sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" + archiveArtifacts "test_results-${JOB_NAME}.html" + } + } + } + } + } + } + } + + post { + always { + script { + if (params.pipelineZipsConsoleLog != null) { + if (params.pipelineZipsConsoleLog) { + echo "Archiving Jenkins console log" + sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true" + sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true" + if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip" + } + } + } + } + } + } +} diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa b/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa new file mode 100644 index 0000000000..66d12eed33 --- /dev/null +++ b/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa @@ -0,0 +1,297 @@ +#!/bin/groovy +/* + * 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 + */ + +// Template Jenkins Declarative Pipeline script to run Test w/ RF HW + +// Location of the python executor node shall be in the same subnet as the others servers +def pythonExecutor = params.pythonExecutor + +// Location of the test XML file to be run +def testXMLFile = params.pythonTestXmlFile +def mainPythonAllXmlFiles = "" +def buildStageStatus = true + +// Name of the test stage +def testStageName = params.pipelineTestStageName + +// Name of the phone resource +def ciSmartPhonesResource1 = params.SmartPhonesResource1 +def ciSmartPhonesResource2 = params.SmartPhonesResource2 +def ciSmartPhonesResource3 = params.SmartPhonesResource3 + +// Global Parameters. Normally they should be populated when the master job +// triggers the slave job with parameters +def eNB_Repository +def eNB_Branch +def eNB_CommitID +def eNB_AllowMergeRequestProcess +def eNB_TargetBranch + +pipeline { + agent { + label pythonExecutor + } + options { + disableConcurrentBuilds() + ansiColor('xterm') + lock(extra: [[resource: ciSmartPhonesResource2],[resource: ciSmartPhonesResource3]], resource: ciSmartPhonesResource1) + } + stages { + stage("Build Init") { + steps { + // update the build name and description + buildName "${params.eNB_MR}" + buildDescription "Branch : ${params.eNB_Branch}" + } + } + stage ("Verify Parameters") { + steps { + script { + echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' + def allParametersPresent = true + + // It is already to late to check it + if (params.pythonExecutor != null) { + echo "eNB CI executor node : ${pythonExecutor}" + } + // If not present picking a default Stage Name + if (params.pipelineTestStageName == null) { + // picking default + testStageName = 'Template Test Stage' + } + + if (params.SmartPhonesResource1 == null) { + allParametersPresent = false + } + if (params.SmartPhonesResource2 == null) { + allParametersPresent = false + } + if (params.SmartPhonesResource3== null) { + allParametersPresent = false + } + // 1st eNB parameters + if (params.eNB_IPAddress == null) { + allParametersPresent = false + } + if (params.eNB_SourceCodePath == null) { + allParametersPresent = false + } + if (params.eNB_Credentials == null) { + allParametersPresent = false + } + // 2nd eNB parameters + if (params.eNB1_IPAddress == null) { + allParametersPresent = false + } + if (params.eNB1_SourceCodePath == null) { + allParametersPresent = false + } + if (params.eNB1_Credentials == null) { + allParametersPresent = false + } + // 3rd eNB parameters + if (params.eNB2_IPAddress == null) { + allParametersPresent = false + } + if (params.eNB2_SourceCodePath == null) { + allParametersPresent = false + } + if (params.eNB2_Credentials == null) { + allParametersPresent = false + } + // the following 4 parameters should be pushed by the master trigger + // if not present, take the job GIT variables (used for developing) + if (params.eNB_Repository == null) { + eNB_Repository = env.GIT_URL + } else { + eNB_Repository = params.eNB_Repository + } + echo "eNB_Repository : ${eNB_Repository}" + if (params.eNB_Branch == null) { + eNB_Branch = env.GIT_BRANCH + } else { + eNB_Branch = params.eNB_Branch + } + echo "eNB_Branch : ${eNB_Branch}" + if (params.eNB_CommitID == null) { + eNB_CommitID = env.GIT_COMMIT + } else { + eNB_CommitID = params.eNB_CommitID + } + echo "eNB_CommitID : ${eNB_CommitID}" + if (params.eNB_AllowMergeRequestProcess!= null) { + eNB_AllowMergeRequestProcess = params.eNB_AllowMergeRequestProcess + if (eNB_AllowMergeRequestProcess) { + if (params.eNB_TargetBranch != null) { + eNB_TargetBranch = params.eNB_TargetBranch + } else { + eNB_TargetBranch = 'develop' + } + echo "eNB_TargetBranch : ${eNB_TargetBranch}" + } + } + + if (params.EPC_IPAddress == null) { + allParametersPresent = false + } + if (params.EPC_Type == null) { + allParametersPresent = false + } + if (params.EPC_SourceCodePath == null) { + allParametersPresent = false + } + if (params.EPC_Credentials == null) { + allParametersPresent = false + } + + if (params.ADB_IPAddress == null) { + allParametersPresent = false + } + if (params.ADB_Credentials == null) { + allParametersPresent = false + } + + if (allParametersPresent) { + echo "All parameters are present" + if (eNB_AllowMergeRequestProcess) { + sh "git fetch" + sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" + } else { + sh "git fetch" + sh "git checkout -f ${eNB_CommitID}" + } + } else { + echo "Some parameters are missing" + sh "./ci-scripts/fail.sh" + } + } + } + } + stage ("Build and Test") { + steps { + script { + dir ('ci-scripts') { + echo "\u2705 \u001B[32m${testStageName}\u001B[0m" + // If not present picking a default XML file + if (params.pythonTestXmlFile == null) { + // picking default + testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' + echo "Test XML file(default): ${testXMLFile}" + mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " + } else { + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { + mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " + echo "Test XML file : ${xmlFile}" + } + } + } + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] + ]) { + sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { + try { + sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + } catch (Exception e) { + currentBuild.result = 'FAILURE' + buildStageStatus = false + } + } + } + sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" + } + } + } + } + } + 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 (eNB - Run)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m' + sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("enb.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "enb.log.${env.BUILD_ID}.zip" + } + if(fileExists("ci-scripts/test_results.html")) { + sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html" + sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" + archiveArtifacts "test_results-${JOB_NAME}.html" + } + } + } + } + } + } + } + + post { + always { + script { + if (params.pipelineZipsConsoleLog != null) { + if (params.pipelineZipsConsoleLog) { + echo "Archiving Jenkins console log" + sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true" + sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true" + if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip" + } + } + } + } + } + } +} diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index ab1573de7f..7d5307620f 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -241,6 +241,10 @@ pipeline { stage ("Terminate") { parallel { stage('Terminate UE') { + // Bypassing this stage if there are no abd server defined + when { + expression { params.ADB_IPAddress != "none" } + } steps { echo '\u2705 \u001B[32mTerminate UE\u001B[0m' withCredentials([ @@ -275,6 +279,10 @@ pipeline { } } stage('Terminate SPGW') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } steps { echo '\u2705 \u001B[32mTerminate SPGW\u001B[0m' withCredentials([ @@ -292,6 +300,10 @@ pipeline { } } stage('Terminate MME') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } steps { echo '\u2705 \u001B[32mTerminate MME\u001B[0m' withCredentials([ @@ -309,6 +321,10 @@ pipeline { } } stage('Terminate HSS') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } steps { echo '\u2705 \u001B[32mTerminate HSS\u001B[0m' withCredentials([ @@ -371,6 +387,10 @@ pipeline { } } stage('Log Collection (SPGW)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } steps { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] @@ -389,6 +409,10 @@ pipeline { } } stage('Log Collection (MME)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } steps { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] @@ -407,6 +431,10 @@ pipeline { } } stage('Log Collection (HSS)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } steps { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] @@ -425,6 +453,10 @@ pipeline { } } stage('Log Collection (Ping)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } steps { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] @@ -443,6 +475,10 @@ pipeline { } } stage('Log Collection (Iperf)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } steps { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] @@ -482,7 +518,7 @@ pipeline { // Making sure that we really shutdown every thing before leaving failure { script { - if (!termStatusArray[termUE]) { + if ((!termStatusArray[termUE]) && (params.ADB_IPAddress != "none")) { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] ]) { @@ -496,21 +532,21 @@ pipeline { sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" } } - if (!termStatusArray[termSPGW]) { + if ((!termStatusArray[termSPGW]) && (params.EPC_IPAddress != "none")) { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] ]) { sh "python3 ci-scripts/main.py --mode=TerminateSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}" } } - if (!termStatusArray[termMME]) { + if ((!termStatusArray[termMME]) && (params.EPC_IPAddress != "none")) { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] ]) { sh "python3 ci-scripts/main.py --mode=TerminateMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}" } } - if (!termStatusArray[termHSS]) { + if ((!termStatusArray[termHSS]) && (params.EPC_IPAddress != "none")) { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] ]) { diff --git a/ci-scripts/Jenkinsfile-trig-nsa b/ci-scripts/Jenkinsfile-trig-nsa new file mode 100644 index 0000000000..3dd5ce3b50 --- /dev/null +++ b/ci-scripts/Jenkinsfile-trig-nsa @@ -0,0 +1,73 @@ +#!/bin/groovy +/* + * 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 + */ + +// Template Jenkins Declarative Pipeline script to run Test w/ RF HW + +// Location of the python executor node shall be in the same subnet as the others servers +def pythonExecutor = params.pythonExecutor + +def TARGET_BRANCH = "develop" +def ALLOW_MERGE = true + +pipeline { + agent { + label pythonExecutor + } + stages { + stage ("Launcher") { + steps { + script { + //retrieve MR that are opened nd with tag READY_TO_BE_MERGED + MR_LIST= sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=READY_TO_BE_MERGED" | jq ".[].iid" || true ' + echo "List of selected MR:\n${MR_LIST}" + def MR_ARRAY = MR_LIST.split('\n') + //for every selected MR, retrieve the branch name and the latest commit + for (MR in MR_ARRAY) { + SRC_BRANCH=sh returnStdout: true, script: """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".source_branch" || true """ + SRC_BRANCH=SRC_BRANCH.trim() + COMMIT_ID=sh returnStdout: true, script: """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".sha" || true """ + COMMIT_ID=COMMIT_ID.trim() + echo "Testing NSA on : ${MR} ${SRC_BRANCH} ${COMMIT_ID}" + //calling NSA sub job + build job: "RAN-CI-NSA-B210", wait : false, propagate : false, parameters: [ + string(name: 'eNB_MR', value: String.valueOf(MR)), + string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)), + string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)), + string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)), + booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE)) + ] + //calling Benetel sub job + build job: "RAN-CI-BENETEL", wait : false, propagate : false, parameters: [ + string(name: 'eNB_MR', value: String.valueOf(MR)), + string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)), + string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)), + string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)), + booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE)) + ] + } + } + } + } + } +} + + diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 861cab0782..2b1a5e0c71 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -62,6 +62,12 @@ function build_on_vm { echo "ARCHIVES_LOC = $ARCHIVES_LOC" echo "BUILD_OPTIONS = $BUILD_OPTIONS" + if [[ "$VM_NAME" == *"-enb-usrp"* ]] + then + echo "This VM type is no longer supported in the pipeline framework" + return + fi + IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME` if [ $IS_VM_ALIVE -eq 0 ] @@ -158,6 +164,9 @@ function build_on_vm { echo "cd tmp" >> $VM_CMDS echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $VM_CMDS echo "unzip -qq -DD ../localZip.zip" >> $VM_CMDS + # Trying to make some room on filesystem before building + echo "rm ../localZip.zip" >> $VM_CMDS + echo "export CI_ENV=True" >> $VM_CMDS if [[ "$VM_NAME" == *"-cppcheck"* ]] then echo "mkdir cmake_targets/log" >> $VM_CMDS @@ -208,7 +217,15 @@ function build_on_vm { echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS else - echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + if [[ "$VM_NAME" == *"-enb-ethernet"* ]] + then + echo "echo \"sleep 170 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + elif [[ "$VM_NAME" == *"-ue-ethernet"* ]] + then + echo "echo \"sleep 60 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + else + echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + fi echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS echo "echo \"sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh\"" >> $VM_CMDS echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 0c07dfe91f..0debe42468 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -35,6 +35,7 @@ import sys # arg import re # reg import logging import os +import shutil import time from multiprocessing import Process, Lock, SimpleQueue from zipfile import ZipFile @@ -124,7 +125,7 @@ class Containerize(): self.cli = 'docker' self.dockerfileprefix = '.ubuntu18' elif self.host == 'Red Hat': - self.cli = 'podman' + self.cli = 'sudo podman' self.dockerfileprefix = '.rhel8.2' imageNames = [] @@ -173,6 +174,7 @@ class Containerize(): # 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' + sharedTag = 'develop' if (self.ranAllowMerge): imageTag = 'ci-temp' if self.ranTargetBranch == '': @@ -188,38 +190,23 @@ class Containerize(): 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) + mySSH.command(self.cli + ' image prune --force', '\$', 30) + if (not self.ranAllowMerge): + mySSH.command(self.cli + ' image rm ' + sharedimage + ':' + sharedTag, '\$', 30) 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 + mySSH.command(self.cli + ' image rm ' + image + ':' + imageTag, '\$', 30) - imageTag = 'ci-temp' - # First verify if images were properly created. + # Build the shared image only on Push Events (not on Merge Requests) + if (not self.ranAllowMerge): + mySSH.command(self.cli + ' build --target ' + sharedimage + ' --tag ' + sharedimage + ':' + sharedTag + ' --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) + # First verify if the shared image was 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') + mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' ' + sharedimage + ':' + sharedTag, '\$', 5) + if mySSH.getBefore().count('o such image') != 0: + logging.error('\u001B[1m Could not build properly ran-build\u001B[0m') status = False else: result = re.search('Size *= *(?P[0-9\-]+) *bytes', mySSH.getBefore()) @@ -240,11 +227,40 @@ class Containerize(): self.allImagesSize['ran-build'] = str(round(imageSize,1)) + ' Gbytes' else: logging.debug('ran-build size is unknown') + # If the shared image failed, no need to continue + if not status: + # Recover the name of the failed container? + mySSH.command(self.cli + ' ps --quiet --filter "status=exited" -n1 | xargs ' + self.cli + ' rm -f', '\$', 5) + mySSH.command(self.cli + ' image prune --force', '\$', 30) + mySSH.close() + logging.error('\u001B[1m Building OAI Images Failed\u001B[0m') + HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTabFooter(False) + sys.exit(1) + else: + # Recover build logs, for the moment only possible when build is successful + mySSH.command(self.cli + ' create --name test ' + sharedimage + ':' + sharedTag, '\$', 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) + + # Build the target image(s) 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 + ':' + sharedTag + '#" 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) + # split the log + mySSH.command('mkdir -p cmake_targets/log/' + image, '\$', 5) + mySSH.command('python3 ci-scripts/docker_log_split.py --logfilename=cmake_targets/log/' + image + '.log', '\$', 5) + # checking the status of the build 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) + if mySSH.getBefore().count('o such image') != 0: + logging.error('\u001B[1m Could not build properly ' + image + '\u001B[0m') status = False + # Here we should check if the last container corresponds to a failed command and destroy it + mySSH.command(self.cli + ' ps --quiet --filter "status=exited" -n1 | xargs ' + self.cli + ' rm -f', '\$', 5) + self.allImagesSize[image] = 'N/A -- Build Failed' else: result = re.search('Size *= *(?P[0-9\-]+) *bytes', mySSH.getBefore()) if result is not None: @@ -264,39 +280,27 @@ class Containerize(): 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) + self.allImagesSize[image] = 'unknown' + # Now pruning dangling images in between target builds + mySSH.command(self.cli + ' image prune --force', '\$', 30) - # 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) + # Analyzing the logs + mySSH.command('cd ' + lSourcePath + '/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) + + mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) + mySSH.command('rm -f build_log_' + self.testCase_id + '.zip || true', '\$', 5) if (os.path.isfile('./build_log_' + self.testCase_id + '.zip')): os.remove('./build_log_' + self.testCase_id + '.zip') + if (os.path.isdir('./build_log_' + self.testCase_id)): + shutil.rmtree('./build_log_' + self.testCase_id) 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.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') @@ -328,9 +332,16 @@ class Containerize(): 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) + if status: + 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) + else: + 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) def DeployObject(self, HTML, EPC): if self.eNB_serverId[self.eNB_instance] == '0': diff --git a/ci-scripts/conf_files/benetel-4g.conf b/ci-scripts/conf_files/benetel-4g.conf new file mode 100644 index 0000000000..9423ebe56e --- /dev/null +++ b/ci-scripts/conf_files/benetel-4g.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 = 0xe00; + + 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 = 222; mnc = 01; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + 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 = 2655000000L; + uplink_frequency_offset = -120000000; + 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; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 90; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + 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 = -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"; + 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 = 640000; + } + ); + + + 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 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_measurement_reports = "yes"; + + ///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 = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.1"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +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"; + prach_dtx_threshold = 150; + } +); + +RUs = ( + { + //local_if_name = "enp129s0f0"; + local_if_name = "dpdk"; + 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"; + #local_portc = 50000; + #remote_portc = 50000; + #local_portd = 50001; + #remote_portd = 50001; + local_rf = "no" + tr_preference = "raw_if4p5" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + 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"; + parallel_config = "PARALLEL_SINGLE_THREAD"; + #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"; +}; + + 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/benetel-5g.conf b/ci-scripts/conf_files/benetel-5g.conf new file mode 100644 index 0000000000..c9f0a579e1 --- /dev/null +++ b/ci-scripts/conf_files/benetel-5g.conf @@ -0,0 +1,303 @@ +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 = 01; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 31; //0; + pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + #pusch_TargetSNRx10 = 200; + #pucch_TargetSNRx10 = 200; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is is the central frequency of SSB + absoluteFrequencySSB = 640000; //641272 + dl_frequencyBand = 78; + # the carrier frequency is assumed to be in the middle of the carrier, i.e. dl_absoluteFrequencyPointA_kHz + dl_carrierBandwidth*12*SCS_kHz/2 + dl_absoluteFrequencyPointA = 638728; //640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=84,L=13 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6368; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + + #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 = 6368; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 4; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 74; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; + #preambleReceivedTargetPower = -104; + #preambleReceivedTargetPower = -108; +#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 = 2; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 5; +#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; //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 = 1; + 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; # used for UL slot + initialULBWPmappingType_0 = 1 + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 + + initialULBWPk2_1 = 6; # used for mixed slot + initialULBWPmappingType_1 = 1; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 + + initialULBWPk2_2 = 7; # used for Msg.3 during RA + initialULBWPmappingType_2 = 1; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 + + + msg3_DeltaPreamble = 1; + #p0_NominalWithGrant =-90; + p0_NominalWithGrant =-118; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + #p0_nominal = -90; + p0_nominal = -118; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; #0x80; + +# 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; //8; //7; + nrofDownlinkSymbols = 6; //0; //6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; //0; //4; + + #ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -35; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; + 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 */ + target_enb_x2_ip_address = ( + { ipv4 = "127.0.0.1"; + 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 = "127.0.0.2/24"; + 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"; + pusch_proc_threads = 8; + } +); + +RUs = ( + { + local_rf = "no" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + //clock_src = "internal"; + clock_src = "external"; + + local_if_name = "dpdk"; + 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; + remote_portc = 50000; + local_portd = 50001; + remote_portd = 50001; + tr_preference = "raw_if4p5" + + } +); + +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"; + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + + 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/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf new file mode 100644 index 0000000000..0da833b3f7 --- /dev/null +++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf @@ -0,0 +1,301 @@ +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 = 311; mnc = 480; mnc_length = 3;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is pointA + 23 PRBs@120kHz SCS (same as initial BWP) + absoluteFrequencySSB = 2071241; + dl_frequencyBand = 261; + # this is 27.900 GHz + dl_absoluteFrequencyPointA = 2070833; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 3; + dl_carrierBandwidth = 32; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=32 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 8525; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 3; + #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=3 + 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 //5 (4 is for 43, 5 is for 57) + initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 261; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 3; + ul_carrierBandwidth = 32; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 8525; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 3; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 52; +#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 = 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 = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + 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 +#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 = 3, + +# 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 = 14; + 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 = 3; + ssb_PositionsInBurst_Bitmap = 0x0001000100010001L; + +# 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 = 3; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 3; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 3; + 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.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.18.198/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + 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 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + } +); + +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]; + sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; + if_freq = 5124520000L; + clock_src = "external"; + time_src = "external"; + } +); + +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/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf new file mode 100644 index 0000000000..b8a601ce41 --- /dev/null +++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf @@ -0,0 +1,293 @@ +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; + pusch_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 = -25; + } + + ); + + + # ------- 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"; + pusch_proc_threads = 8; + } +); + +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 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"; + # 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/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index aeba400cad..b1d72c2269 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -23,7 +23,8 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; - + pusch_AntennaPorts = 1; + servingCellConfigCommon = ( { #spCellConfigCommon @@ -46,7 +47,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=41,L=24 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -89,7 +90,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -186,7 +187,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); @@ -227,19 +228,20 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + pusch_proc_threads = 8; + } ); RUs = ( { - local_rf = "yes" + local_rf = "yes" nb_tx = 1 nb_rx = 1 att_tx = 0 @@ -248,8 +250,15 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 75; 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/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index 258618e7f0..7be25a24fa 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -22,6 +22,7 @@ gNBs = ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; @@ -48,7 +49,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -90,7 +91,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -250,7 +251,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - pusch_proc_threads = 8; + pusch_proc_threads = 6; } ); diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh index 237a1a5d5e..b67668f0bc 100755 --- a/ci-scripts/createVM.sh +++ b/ci-scripts/createVM.sh @@ -87,6 +87,12 @@ function create_vm { echo "VM_CPU = $VM_CPU" echo "VM_DISK = $VM_DISK GBytes" + if [[ "$VM_NAME" == *"-enb-usrp"* ]] + then + echo "This VM type is no longer supported in the pipeline framework" + return + fi + echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" diff --git a/ci-scripts/docker_log_split.py b/ci-scripts/docker_log_split.py new file mode 100644 index 0000000000..8c3c9e41dc --- /dev/null +++ b/ci-scripts/docker_log_split.py @@ -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 +# * +# * 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 Libs +#----------------------------------------------------------- +import sys # arg +import re # reg +import os +import subprocess + + +class SplitReport(): + def __init__(self): + self.logfilename = '' + self.destinationFolder = '' + + def split(self): + self.destinationFolder = self.logfilename.replace(".log","") + if os.path.isfile(self.logfilename): + newImageLog = open(self.logfilename + '.new', 'w') + copyFlag = True + with open(self.logfilename, 'r') as imageLog: + for line in imageLog: + header = False + ret = re.search('====== Start of log for ([0-9\.A-Za-z\-\_]+) ======', line) + if ret is not None: + copyFlag = False + header = True + detailedLogFile = open(self.destinationFolder + '/' + ret.group(1), 'w') + if copyFlag: + newImageLog.write(line) + ret = re.search('====== End of log for ([0-9\.A-Za-z\-\_]+) ======', line) + if ret is not None: + copyFlag = True + detailedLogFile.close() + elif not copyFlag and not header: + detailedLogFile.write(line) + imageLog.close() + newImageLog.close() + os.rename(self.logfilename + '.new', self.logfilename) + else: + print('Cannot split unfound file') + +#-------------------------------------------------------------------------------------------------------- +# +# Start of main +# +#-------------------------------------------------------------------------------------------------------- + +argvs = sys.argv +argc = len(argvs) + +SP = SplitReport() + +while len(argvs) > 1: + myArgv = argvs.pop(1) + if re.match('^\-\-logfilename=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-logfilename=(.+)$', myArgv, re.IGNORECASE) + SP.logfilename = matchReg.group(1) + +SP.split() + +sys.exit(0) diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 9b9fe462f1..d8f088b707 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -172,6 +172,7 @@ function setvar_usage { function variant__v1__enb_usrp { NB_PATTERN_FILES=9 BUILD_OPTIONS="--eNB -w USRP --mu" + VM_MEMORY=3072 } function variant__v2__basic_sim { @@ -213,15 +214,15 @@ function variant__v6__nr_ue_usrp { function variant__v7__enb_ethernet { VM_MEMORY=4096 ARCHIVES_LOC=enb_eth - NB_PATTERN_FILES=8 - BUILD_OPTIONS="--eNB" + NB_PATTERN_FILES=9 + BUILD_OPTIONS="--eNB -w USRP" } function variant__v8__ue_ethernet { VM_MEMORY=4096 ARCHIVES_LOC=ue_eth - NB_PATTERN_FILES=12 - BUILD_OPTIONS="--UE" + NB_PATTERN_FILES=13 + BUILD_OPTIONS="--UE -w USRP" } function variant__v10__flexran_rtc { diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 774d7f19c6..783adb98e6 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -239,6 +239,7 @@ class RANManagement(): while (count > 0) and buildOAIprocess: mySSH.command('ps aux | grep --color=never build_ | grep -v grep', '\$', 6) result = re.search('build_oai', mySSH.getBefore()) + print(result) if result is None: buildOAIprocess = False else: @@ -464,7 +465,7 @@ class RANManagement(): self.prematureExit = True return else: - mySSH.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting"', '\$', 4) + mySSH.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting|Started"', '\$', 4) if rruCheck: result = re.search('wait RUs', mySSH.getBefore()) else: diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index 44d200c3b6..19a486303f 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -580,16 +580,42 @@ function report_build { sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder sca_summary_table_footer ./archives/cppcheck/cppcheck.xml - summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp - summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html - summary_table_row "Coding - Release 15" ./archives/enb_usrp/coding.Rel15.txt "Built target coding" ./enb_usrp_row2.html - summary_table_row "OAI USRP device if - Release 15" ./archives/enb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html - summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html - summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_usrp_row5.html - summary_table_row "NASMESH - Release 15" ./archives/enb_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./enb_usrp_row6.html - summary_table_row "RB Tool - Release 15" ./archives/enb_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./enb_usrp_row7.html - summary_table_row "RF Simulator - Release 15" ./archives/enb_usrp/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_usrp_row8.html - summary_table_row "TCP Bridge - Release 15" ./archives/enb_usrp/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_usrp_row9.html +# summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp +# summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html +# summary_table_row "Coding - Release 15" ./archives/enb_usrp/coding.Rel15.txt "Built target coding" ./enb_usrp_row2.html +# summary_table_row "OAI USRP device if - Release 15" ./archives/enb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html +# summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html +# summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_usrp_row5.html +# summary_table_row "NASMESH - Release 15" ./archives/enb_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./enb_usrp_row6.html +# summary_table_row "RB Tool - Release 15" ./archives/enb_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./enb_usrp_row7.html +# summary_table_row "RF Simulator - Release 15" ./archives/enb_usrp/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_usrp_row8.html +# summary_table_row "TCP Bridge - Release 15" ./archives/enb_usrp/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_usrp_row9.html +# summary_table_footer +# + summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_eth + summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html + summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html + summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_eth_row3.html + summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_eth_row4.html + summary_table_row "RF Simulator - Release 15" ./archives/enb_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_eth_row5.html + summary_table_row "TCP OAI Bridge - Release 15" ./archives/enb_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html + summary_table_row "OAI USRP device if - Release 15" ./archives/enb_eth/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_eth_row7.html + summary_table_row "NASMESH - Release 15" ./archives/enb_eth/nasmesh.Rel15.txt "Built target nasmesh" ./enb_eth_row8.html + summary_table_row "RB Tool - Release 15" ./archives/enb_eth/rb_tool.Rel15.txt "Built target rb_tool" ./enb_eth_row9.html + summary_table_footer + + summary_table_header "OAI Build: 4G LTE UE -- USRP option" ./archives/ue_eth + summary_table_row "LTE UE SoftModem - Release 15" ./archives/ue_eth/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html + summary_table_row "Coding - Release 15" ./archives/ue_eth/coding.Rel15.txt "Built target coding" ./ue_eth_row2.html + summary_table_row "OAI ETHERNET transport - Release 15" ./archives/ue_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./ue_eth_row3.html + summary_table_row "Parameters Lib Config - Release 15" ./archives/ue_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./ue_eth_row4.html + summary_table_row "RF Simulator - Release 15" ./archives/ue_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./ue_eth_row5.html + summary_table_row "TCP OAI Bridge - Release 15" ./archives/ue_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./ue_eth_row6.html + summary_table_row "Conf 2 UE Data - Release 15" ./archives/ue_eth/conf2uedata.Rel15.txt "Built target conf2uedata" ./ue_eth_row7.html + summary_table_row "NVRAM - Release 15" ./archives/ue_eth/nvram.Rel15.txt "Built target nvram" ./ue_eth_row8.html + summary_table_row "UE IP - Release 15" ./archives/ue_eth/ue_ip.Rel15.txt "Built target ue_ip" ./ue_eth_row9.html + summary_table_row "USIM - Release 15" ./archives/ue_eth/usim.Rel15.txt "Built target usim" ./ue_eth_row9a.html + summary_table_row "OAI USRP device if - Release 15" ./archives/ue_eth/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./ue_eth_row9b.html summary_table_footer summary_table_header "OAI Build: 4G LTE basic simulator option" ./archives/basic_sim @@ -676,28 +702,6 @@ function report_build { summary_table_footer fi - summary_table_header "OAI Build: 4G LTE eNB -- ETHERNET transport option" ./archives/enb_eth - summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html - summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html - summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_eth_row3.html - summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_eth_row4.html - summary_table_row "RF Simulator - Release 15" ./archives/enb_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_eth_row5.html - summary_table_row "TCP OAI Bridge - Release 15" ./archives/enb_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html - summary_table_footer - - summary_table_header "OAI Build: 4G LTE UE -- ETHERNET transport option" ./archives/ue_eth - summary_table_row "LTE UE SoftModem - Release 15" ./archives/ue_eth/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html - summary_table_row "Coding - Release 15" ./archives/ue_eth/coding.Rel15.txt "Built target coding" ./ue_eth_row2.html - summary_table_row "OAI ETHERNET transport - Release 15" ./archives/ue_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./ue_eth_row3.html - summary_table_row "Parameters Lib Config - Release 15" ./archives/ue_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./ue_eth_row4.html - summary_table_row "RF Simulator - Release 15" ./archives/ue_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./ue_eth_row5.html - summary_table_row "TCP OAI Bridge - Release 15" ./archives/ue_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./ue_eth_row6.html - summary_table_row "Conf 2 UE Data - Release 15" ./archives/ue_eth/conf2uedata.Rel15.txt "Built target conf2uedata" ./ue_eth_row7.html - summary_table_row "NVRAM - Release 15" ./archives/ue_eth/nvram.Rel15.txt "Built target nvram" ./ue_eth_row8.html - summary_table_row "UE IP - Release 15" ./archives/ue_eth/ue_ip.Rel15.txt "Built target ue_ip" ./ue_eth_row9.html - summary_table_row "USIM - Release 15" ./archives/ue_eth/usim.Rel15.txt "Built target usim" ./ue_eth_row9a.html - summary_table_footer - if [ -e ./archives/red_hat ] then echo "

Red Hat Enterprise Linux Server release 7.6) -- Summary

" >> ./build_results.html @@ -714,9 +718,23 @@ function report_build { echo " " >> ./build_results.html echo "
" >> ./build_results.html - if [ -f ./enb_usrp_row1.html ] || [ -f ./enb_usrp_row2.html ] || [ -f ./enb_usrp_row3.html ] || [ -f ./enb_usrp_row4.html ] +# if [ -f ./enb_usrp_row1.html ] || [ -f ./enb_usrp_row2.html ] || [ -f ./enb_usrp_row3.html ] || [ -f ./enb_usrp_row4.html ] +# then +# for DETAILS_TABLE in `ls ./enb_usrp_row*.html` +# do +# cat $DETAILS_TABLE >> ./build_results.html +# done +# fi + if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ] || [ -f ./enb_eth_row7.html ] || [ -f ./enb_eth_row8.html ] || [ -f ./enb_eth_row9.html ] then - for DETAILS_TABLE in `ls ./enb_usrp_row*.html` + for DETAILS_TABLE in `ls ./enb_eth_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + fi + if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ] || [ -f ./ue_eth_row7.html ] || [ -f ./ue_eth_row8.html ] || [ -f ./ue_eth_row9.html ] || [ -f ./ue_eth_row9a.html ] || [ -f ./ue_eth_row9b.html ] + then + for DETAILS_TABLE in `ls ./ue_eth_row*.html` do cat $DETAILS_TABLE >> ./build_results.html done @@ -749,20 +767,6 @@ function report_build { cat $DETAILS_TABLE >> ./build_results.html done fi - if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ] - then - for DETAILS_TABLE in `ls ./enb_eth_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - fi - if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ] - then - for DETAILS_TABLE in `ls ./ue_eth_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - fi if [ -f ./enb_usrp_rh_row1.html ] || [ -f ./enb_usrp_rh_row2.html ] || [ -f ./enb_usrp_rh_row3.html ] || [ -f ./enb_usrp_rh_row4.html ] then for DETAILS_TABLE in `ls ./enb_usrp_rh_row*.html` diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 8562f4b2de..c4fa817b06 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -750,6 +750,77 @@ function report_test { EPC_CONFIGS=("noS1") TRANS_MODES=("tdd") + FR_MODE=("FR2") + BW_CASES=(32) + for CN_CONFIG in ${EPC_CONFIGS[@]} + do + for TMODE in ${TRANS_MODES[@]} + do + for BW in ${BW_CASES[@]} + do + echo " " >> ./test_simulator_results.html + if [[ $CN_CONFIG =~ .*wS1.* ]] + then + echo " Test with EPC (aka withS1): ${TMODE} -- ${BW}PRB -- ${FR_MODE}" >> ./test_simulator_results.html + else + echo " Test without EPC (aka noS1): ${TMODE} -- ${BW}PRB -- ${FR_MODE}" >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + + + #FR2 RA test (--do-ra option) + + #build log files names tdd_${PRB}prb_${CN_CONFIG}_gnb_ra_fr2_test.log + + RA_ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb_ra_fr2_test.log + RA_UE_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_ue_ra_fr2_test.log + if [ -f $RA_ENB_LOG ] && [ -f $RA_UE_LOG ] + then + #get rid of full path + NAME_ENB=`echo $RA_ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` + NAME_UE=`echo $RA_UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + echo " $NAME_ENB --- $NAME_UE" >> ./test_simulator_results.html + echo " Check if FR2 RA proc succeeded" >> ./test_simulator_results.html + + #gNB RA check + GNB_RECEIVED=`egrep -c "\[RAPROC\] PUSCH with TC_RNTI (.+) received correctly" $RA_ENB_LOG` + #UE RA check + UE_RA_PROC_OK=`egrep -c "\[RAPROC\] RA procedure succeeded" $RA_UE_LOG` + + + if [ $GNB_RECEIVED -gt 0 ] && [ $UE_RA_PROC_OK -gt 0 ] + then + echo " OK" >> ./test_simulator_results.html + else + echo " KO" >> ./test_simulator_results.html + fi + + echo "
" >> ./test_simulator_results.html
+                    if [ $GNB_RECEIVED -gt 0 ]
+                    then
+                        echo "- gNB --> RA received" >> ./test_simulator_results.html
+                    else
+                        echo "- gNB RA NOT RECEIVED" >> ./test_simulator_results.html
+                    fi
+                    if [ $UE_RA_PROC_OK -gt 0 ]
+                    then
+                        echo "- NR UE  --> RA procedure succeded" >> ./test_simulator_results.html
+                    else
+                        echo "- NR UE RA procedure failed" >> ./test_simulator_results.html
+                    fi
+                    echo "        
" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + fi + + done + done + done + + + EPC_CONFIGS=("noS1") + FR_MODE=("FR1") + TRANS_MODES=("fdd" "tdd") BW_CASES=(106) for CN_CONFIG in ${EPC_CONFIGS[@]} do @@ -760,13 +831,14 @@ function report_test { echo " " >> ./test_simulator_results.html if [[ $CN_CONFIG =~ .*wS1.* ]] then - echo " Test with EPC (aka withS1): ${TMODE} -- ${BW}PRB " >> ./test_simulator_results.html + echo " Test with EPC (aka withS1): ${TMODE} -- ${BW}PRB -- ${FR_MODE}" >> ./test_simulator_results.html else - echo " Test without EPC (aka noS1): ${TMODE} -- ${BW}PRB " >> ./test_simulator_results.html + echo " Test without EPC (aka noS1): ${TMODE} -- ${BW}PRB -- ${FR_MODE}" >> ./test_simulator_results.html fi echo " " >> ./test_simulator_results.html - #RA test (--do-ra option) + + #FR1 RA test (--do-ra option) #build log files names RA_ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb_ra_test.log @@ -778,7 +850,7 @@ function report_test { NAME_UE=`echo $RA_UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` echo " " >> ./test_simulator_results.html echo " $NAME_ENB --- $NAME_UE" >> ./test_simulator_results.html - echo " Check if RA proc succeeded" >> ./test_simulator_results.html + echo " Check if FR1 RA proc succeeded" >> ./test_simulator_results.html #gNB RA check GNB_RECEIVED=`egrep -c "\[RAPROC\] PUSCH with TC_RNTI (.+) received correctly" $RA_ENB_LOG` diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 70eabb7b69..6725d2f62b 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -379,7 +379,7 @@ function check_iperf { local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl` local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim` local LOC_IS_RF_SIM=`echo $LOC_BASE_LOG | grep -c rf_sim` - local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c tdd_106prb` + local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c _106prb` if [ -f ${LOC_BASE_LOG}_client.txt ] then local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt` @@ -2189,11 +2189,15 @@ function run_test_on_vm { if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] then + echo "############################################################" + echo "RA TEST FR2" + echo "############################################################" + #RA FR2 test, attention : has a different config file from the rest of the test CN_CONFIG="noS1" - CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf + CONF_FILE=gnb.band261.tm1.32PRB.usrpn300.conf S1_NOS1_CFG=0 - PRB=106 - FREQUENCY=3510 + PRB=32 + FREQUENCY=28000 #28GHz if [ ! -d $ARCHIVES_LOC ] then @@ -2208,20 +2212,20 @@ function run_test_on_vm { do SYNC_STATUS=0 - RA_STATUS=0 - rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}*ra_test.log + RA_FR2_STATUS=0 + rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}*ra_fr2_test.log echo "############################################################" echo "${CN_CONFIG} : Starting the gNB" echo "############################################################" - CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb_ra_test.log + CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb_ra_fr2_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_ra_test.log + CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue_ra_fr2_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 ] @@ -2247,48 +2251,159 @@ function run_test_on_vm { #check RA markers in gNB and NR UE log files echo "############################################################" - echo "${CN_CONFIG} : Checking RA on gNB / NR-UE" + echo "${CN_CONFIG} : Checking FR2 RA on gNB / NR-UE" echo "############################################################" # 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 ] + if [ $RA_FR2_STATUS -ne 0 ] then - echo "RA test NOT OK" + echo "RA FR2 test NOT OK" echo "try_cnt = " $try_cnt try_cnt=$((try_cnt+1)) else try_cnt=$((try_cnt+10)) fi done + ########### end RA FR2 test + + sleep 30 + + + echo "############################################################" + echo "RA TEST FR1" + echo "############################################################" + ######### redefine config for the rest of the test + + CN_CONFIG="noS1" + CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf + S1_NOS1_CFG=0 + PRB=106 + FREQUENCY=3510 + + if [ ! -d $ARCHIVES_LOC ] + then + mkdir --parents $ARCHIVES_LOC + fi + + CN_CONFIG="noS1" + S1_NOS1_CFG=0 + + ######### start of RA TEST loop + # for the moment only TDD + TRANS_MODES=("tdd") + for TMODE in ${TRANS_MODES[@]} + do + if [[ $TMODE =~ .*fdd.* ]] + then + CONF_FILE=gnb.band66.tm1.106PRB.usrpn300.conf + PRB=106 + FREQUENCY=37000 + else + CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf + PRB=106 + FREQUENCY=3510 + fi + + local try_cnt=0 + NR_STATUS=0 + while [ $try_cnt -lt 5 ] #5 because it hardly succeed within CI + + do + SYNC_STATUS=0 + RA_STATUS=0 + rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}*ra_test.log + + echo "############################################################" + echo "${CN_CONFIG} : Starting the gNB in ${TMODE} mode (RA TEST)" + echo "############################################################" + CURRENT_GNB_LOG_FILE=${TMODE}_${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 in ${TMODE} mode (RA TEST)" + echo "############################################################" + CURRENT_NR_UE_LOG_FILE=${TMODE}_${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 ] + then + echo "Problem w/ gNB and NR-UE not syncing" + terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2 + terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1 + scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC + SYNC_STATUS=-1 + try_cnt=$((try_cnt+1)) + continue + fi + + echo "############################################################" + echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators" + echo "############################################################" + sleep 20 + terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2 + terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1 + scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC + + #check RA markers in gNB and NR UE log files + echo "############################################################" + echo "${CN_CONFIG} : Checking FR1 RA on gNB / NR-UE" + echo "############################################################" + + # 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 FR1 test NOT OK" + echo "try_cnt = " $try_cnt + try_cnt=$((try_cnt+1)) + else + try_cnt=$((try_cnt+10)) + fi + done + done ########### end RA test sleep 30 - ######### start of PHY TEST loop - try_cnt=0 - while [ $try_cnt -lt 4 ] + SYNC_STATUS=0 + PING_STATUS=0 + IPERF_STATUS=0 + TRANS_MODES=("fdd tdd") + for TMODE in ${TRANS_MODES[@]} do + if [[ $TMODE =~ .*fdd.* ]] + then + CONF_FILE=gnb.band66.tm1.106PRB.usrpn300.conf + PRB=106 + FREQUENCY=37000 + else + CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf + PRB=106 + FREQUENCY=3510 + fi - - 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 + try_cnt=0 + while [ $try_cnt -lt 4 ] + do + rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_gnb.log $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ue.log + rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log + rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_dl*txt $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_ul*txt echo "############################################################" - echo "${CN_CONFIG} : Starting the gNB" + echo "${CN_CONFIG} : Starting the gNB in ${TMODE} mode (PHY TEST)" echo "############################################################" - CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log + CURRENT_GNB_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_gnb.log start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 0 echo "############################################################" - echo "${CN_CONFIG} : Starting the NR-UE" + echo "${CN_CONFIG} : Starting the NR-UE in ${TMODE} mode (PHY TEST)" echo "############################################################" - CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log + CURRENT_NR_UE_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ue.log start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 0 if [ $NR_UE_SYNC -eq 0 ] then @@ -2306,7 +2421,7 @@ function run_test_on_vm { echo "${CN_CONFIG} : Pinging the gNB from NR-UE" echo "############################################################" get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR - PING_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log + PING_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log ping_epc_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $ENB_IP_ADDR $PING_LOG_FILE 1 0 scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 @@ -2315,7 +2430,7 @@ function run_test_on_vm { echo "${CN_CONFIG} : Pinging the NR-UE from gNB" echo "############################################################" get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1 - PING_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log + PING_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log ping_enb_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0 scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 @@ -2324,7 +2439,7 @@ function run_test_on_vm { echo "${CN_CONFIG} : iperf DL -- NR-UE is server and gNB is client" echo "############################################################" THROUGHPUT="30K" - CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_dl + CURR_IPERF_LOG_BASE=${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_dl get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1 generic_iperf $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 @@ -2346,7 +2461,7 @@ function run_test_on_vm { echo "${CN_CONFIG} : iperf UL -- gNB is server and NR-UE is client" echo "############################################################" THROUGHPUT="30K" - CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_ul + CURR_IPERF_LOG_BASE=${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_ul get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1 generic_iperf $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 @@ -2368,6 +2483,7 @@ function run_test_on_vm { else try_cnt=$((try_cnt+10)) fi + done done ######### end of loop full_l2_sim_destroy @@ -2377,6 +2493,7 @@ function run_test_on_vm { echo "Checking run status" echo "############################################################" + if [ $RA_FR2_STATUS -ne 0 ]; then NR_STATUS=-1; fi 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 diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index f066dacd81..ff2129a187 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -47,6 +47,12 @@ function wait_on_vm_build { echo "ARCHIVES_LOC = $ARCHIVES_LOC" echo "BUILD_OPTIONS = $BUILD_OPTIONS" + if [[ "$VM_NAME" == *"-enb-usrp"* ]] + then + echo "This VM type is no longer supported in the pipeline framework" + return + fi + IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME` if [ $IS_VM_ALIVE -eq 0 ] @@ -84,6 +90,12 @@ function wait_on_vm_build { } function check_on_vm_build { + if [[ "$VM_NAME" == *"-enb-usrp"* ]] + then + echo "This VM type is no longer supported in the pipeline framework" + return + fi + echo "############################################################" echo "Creating a tmp folder to store results and artifacts" echo "############################################################" diff --git a/ci-scripts/xml_files/fr1_multi_node_test.xml b/ci-scripts/xml_files/benetel_multi_node_build.xml similarity index 50% rename from ci-scripts/xml_files/fr1_multi_node_test.xml rename to ci-scripts/xml_files/benetel_multi_node_build.xml index 8c56f0bcec..5ac28951b4 100644 --- a/ci-scripts/xml_files/fr1_multi_node_test.xml +++ b/ci-scripts/xml_files/benetel_multi_node_build.xml @@ -21,57 +21,34 @@ --> - test-fr1-tm1 - Test-FR1-TM1 - tasks - 1 + build-tab + Build + wrench - 030000 - 040000 - 000001 - 070001 - 070000 + 000001 000002 - - - - - Initialize_eNB - Initialize eNB - -O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf - 0 - 0 - lte - - - - Initialize_eNB - Initialize gNB (3/4 sampling rate) - -O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E - 1 - 1 - nr - + - IdleSleep - Sleep - 30 - - - - Terminate_eNB - Terminate eNB + Build_eNB + Build eNB + --eNB -t benetel4g -w None + True 0 0 - - Terminate_eNB - Terminate gNB + + + Build_eNB + Build gNB + --gNB -t benetel5g -w None + True 1 1 - + + + diff --git a/ci-scripts/xml_files/benetel_nsa_base.xml b/ci-scripts/xml_files/benetel_nsa_base.xml new file mode 100644 index 0000000000..0aed28dffa --- /dev/null +++ b/ci-scripts/xml_files/benetel_nsa_base.xml @@ -0,0 +1,162 @@ + + + TEST-FR1-TM1 + FR1 + tasks + + 010000 + 030000 + 040000 + 010001 + 000001 + 050000 + 050001 + 000001 + 060000 + 060001 + 000001 + 070000 + 070001 + 010002 + 000001 + 080001 + 080000 + 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/benetel-4g.conf + 0 + 0 + lte + + + + + Initialize_eNB + Initialize gNB + -O ci-scripts/conf_files/benetel-5g.conf + 1 + 1 + nr + + + + IdleSleep + Sleep + 20 + + + + Ping + Ping: 20pings in 20sec + -c 20 + 50 + + + + Ping + Ping: 100pings in 20sec + -c 100 -i 0.2 + 50 + + + + + 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 + + + + + Iperf + iperf (DL/20Mbps/UDP)(20 sec)(single-ue profile) + -u -b 20M -t 20 -i 1 + 50 + single-ue + + + + Iperf + iperf (UL/3Mbps/UDP)(20 sec)(single-ue profile) + -u -b 3M -t 20 -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_image_build.xml b/ci-scripts/xml_files/container_image_build.xml similarity index 93% rename from ci-scripts/xml_files/fr1_image_build.xml rename to ci-scripts/xml_files/container_image_build.xml index 9dd386b646..430729c49c 100644 --- a/ci-scripts/xml_files/fr1_image_build.xml +++ b/ci-scripts/xml_files/container_image_build.xml @@ -22,7 +22,7 @@ --> build-tab - Build + Build Container Images wrench 000001 @@ -31,7 +31,7 @@ Build_Image - Build eNB Image + Build all Images all 0 0 diff --git a/ci-scripts/xml_files/fr1_multi_node_build.xml b/ci-scripts/xml_files/fr1_multi_node_build.xml index 7b4eacef3a..57c4685341 100644 --- a/ci-scripts/xml_files/fr1_multi_node_build.xml +++ b/ci-scripts/xml_files/fr1_multi_node_build.xml @@ -37,6 +37,7 @@ 0 0 True + True @@ -53,6 +54,7 @@ 1 1 True + True diff --git a/ci-scripts/xml_files/fr1_ran_ue_iperf.xml b/ci-scripts/xml_files/fr1_nsa_base.xml similarity index 80% rename from ci-scripts/xml_files/fr1_ran_ue_iperf.xml rename to ci-scripts/xml_files/fr1_nsa_base.xml index 8ead3afc62..96bdc79f0f 100644 --- a/ci-scripts/xml_files/fr1_ran_ue_iperf.xml +++ b/ci-scripts/xml_files/fr1_nsa_base.xml @@ -21,8 +21,8 @@ --> - TEST-FR1-TM1 - FR1 + TEST-NSA-FR1-TM1 + NSA FULL tasks 010000 @@ -31,14 +31,17 @@ 010001 000001 050000 + 050001 000001 060000 060001 000001 + 070000 + 070001 010002 000001 - 070001 - 070000 + 080001 + 080000 010003 @@ -96,6 +99,13 @@ 50 + + Ping + Ping: 100pings in 20sec + -c 100 -i 0.2 + 50 + + Iperf @@ -113,7 +123,26 @@ single-ue + + Iperf + iperf (DL/20Mbps/UDP)(20 sec)(single-ue profile) + -u -b 20M -t 20 -i 1 + 50 + single-ue + + + + Iperf + iperf (UL/3Mbps/UDP)(20 sec)(single-ue profile) + -u -b 3M -t 20 -i 1 -R + 50 + single-ue + + + + + Terminate_eNB Terminate eNB 0 @@ -121,7 +150,7 @@ lte - + Terminate_eNB Terminate gNB 1 diff --git a/ci-scripts/xml_files/fr1_ran_ue_base.xml b/ci-scripts/xml_files/fr1_nsa_base_ref.xml similarity index 80% rename from ci-scripts/xml_files/fr1_ran_ue_base.xml rename to ci-scripts/xml_files/fr1_nsa_base_ref.xml index 847967f81e..fd47db10b2 100644 --- a/ci-scripts/xml_files/fr1_ran_ue_base.xml +++ b/ci-scripts/xml_files/fr1_nsa_base_ref.xml @@ -21,8 +21,8 @@ --> - TEST-FR1-TM1 - FR1 + TEST-NSA-FR1-TM1 + NSA FULL tasks 010000 @@ -32,16 +32,15 @@ 000001 050000 050001 - 050002 - 050002 000001 060000 060001 000001 + 070000 010002 000001 - 070001 - 070000 + 080001 + 080000 010003 @@ -100,13 +99,6 @@ - Ping - Ping: 5pings in 1sec - -c 5 -i 0.2 - 50 - - - Ping Ping: 100pings in 20sec -c 100 -i 0.2 @@ -116,21 +108,40 @@ Iperf - iperf (DL/1Mbps/UDP)(30 sec)(single-ue profile) - -u -b 1M -t 30 -i 1 + iperf (DL/3Mbps/UDP)(20 sec)(single-ue profile) + -u -b 3M -t 20 -i 1 50 single-ue Iperf - iperf (UL/1Mbps/UDP)(30 sec)(single-ue profile) - -u -b 1M -t 30 -i 1 -R + iperf (UL/1Mbps/UDP)(20 sec)(single-ue profile) + -u -b 1M -t 20 -i 1 -R 50 single-ue + + Iperf + iperf (DL/20Mbps/UDP)(20 sec)(single-ue profile) + -u -b 20M -t 20 -i 1 + 50 + single-ue + + + + Iperf + iperf (UL/3Mbps/UDP)(20 sec)(single-ue profile) + -u -b 3M -t 20 -i 1 -R + 50 + single-ue + + + + + Terminate_eNB Terminate eNB 0 @@ -138,7 +149,7 @@ lte - + Terminate_eNB Terminate gNB 1 diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index dca3bd9188..1bfc0f4249 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -333,6 +333,11 @@ else (CUDA_FOUND) ) endif () +if (SANITIZE_ADDRESS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") +endif () + add_definitions("-DASN_DISABLE_OER_SUPPORT") ######################### @@ -832,7 +837,7 @@ add_library(F1AP # Hardware dependant options ################################### -add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4") +add_list1_option(NB_ANTENNAS_RX "4" "Number of antennas in reception" "1" "2" "4") add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "OAI_USRP" "OAI_BLADERF" "OAI_LMSSDR" "OAI_SIMU") @@ -926,6 +931,9 @@ set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidd # Benetel 4G library ###################################################################### + +include_directories ("/usr/include/dpdk") + set(HWLIB_BENETEL_4G_SOURCE ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/benetel.c ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/shared_buffers.c @@ -1967,7 +1975,10 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c ${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/nr_pdcp_sdu.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c ) @@ -2132,7 +2143,23 @@ set (MCE_APP_SRC ${OPENAIR2_DIR}/MCE_APP/mce_app.c ${OPENAIR2_DIR}/MCE_APP/mce_config.c ) +set (MISC_NFAPI_LTE + ${OPENAIR1_DIR}/SCHED/nfapi_lte_dummy.c + ) + +add_library(MISC_NFAPI_LTE_LIB + ${MISC_NFAPI_LTE} + ) + +set (MISC_NFAPI_NR + ${OPENAIR1_DIR}/SCHED/nfapi_nr_dummy.c + ) + + +add_library(MISC_NFAPI_NR_LIB + ${MISC_NFAPI_NR} + ) add_library(L2 ${L2_SRC} ${MAC_SRC} @@ -2884,8 +2911,9 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer) target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB - PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE ${GTPV1U} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 + + RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB + PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) @@ -2924,8 +2952,9 @@ add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_l target_link_libraries (ocp-enb -Wl,--start-group + RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB - 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 + PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_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} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB}) @@ -2994,8 +3023,9 @@ endif() target_link_libraries (lte-uesoftmodem -Wl,--start-group RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB + ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON - PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB + PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES} -Wl,--end-group z dl) @@ -3119,6 +3149,8 @@ target_link_libraries (nr-uesoftmodem -Wl,--start-group 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 MISC_NFAPI_NR_LIB S1AP_LIB S1AP_ENB + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} 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} LIB_5GNAS_GNB -Wl,--end-group z dl) @@ -3296,7 +3328,7 @@ add_executable(nr_dlsim ) 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_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 + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl ) target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR) @@ -3315,7 +3347,7 @@ add_executable(nr_prachsim ${SHLIB_LOADER_SOURCES}) target_link_libraries(nr_prachsim -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB 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) + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl) add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c @@ -3348,7 +3380,7 @@ add_executable(nr_ulsim ) target_link_libraries(nr_ulsim -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 + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl ) target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 6d3424b420..b0511f63cc 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1292,7 +1292,10 @@ (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) + (Test11: SC-FDMA, 216 PRBs), + (Test12: SC-FDMA, 273 PRBs), + (Test13: SC-FDMA, 3 DMRS), + (Test14: MCS 16 50 PRBs 2 RX_Antenna) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1307,10 +1310,14 @@ -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 - -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 + -n100 -s2 -Z + -n100 -s2 -Z -r75 + -n100 -s2 -Z -r216 -R217 + -n100 -s2 -Z -r270 -R273 + -n100 -s2 -Z -U 2 0 2 + -n100 -m16 -s10 -z2 + + 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 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 PUSCH test OK segmentation fault|assertion|exiting|fatal 3 @@ -1323,7 +1330,8 @@ (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) + (Test6: 120kHz SCS, 66 PRBs, Prach format A2), + (Test7: 120kHz SCS, 66 PRBs, High Speed Enabled) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1335,8 +1343,9 @@ -a -s -30 -n 100 -p 63 -R 273 -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 + -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52 + -a -s -30 -n 100 -R 66 -m 3 -c52 -H + nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7 PRACH test OK segmentation fault|assertion|exiting|fatal 3 diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 960b241047..8748e8d807 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -48,8 +48,9 @@ DEADLINE_SCHEDULER_FLAG_USER="" CPU_AFFINITY_FLAG_USER="False" #Only valid when low-latency flag is set to False REL="Rel15" HW="None" -TP="None" +TP="Ethernet" EPC=0 +VERBOSE_CI=0 VERBOSE_COMPILE=0 CFLAGS_PROCESSOR_USER="" RUN_GROUP=0 @@ -67,6 +68,7 @@ USRP_REC_PLAY="False" BUILD_ECLIPSE=0 NR="False" ITTI_SIM="False" +SANITIZE_ADDRESS="False" OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc" trap handle_ctrl_c INT @@ -289,6 +291,9 @@ function main() { esac echo_info "Setting hardware to: $HW" shift 2;; + -t | --transport) + TP=$2 + shift 2;; -P | --phy_simulators) SIMUS_PHY=1 echo_info "Will compile dlsim, ulsim, ..." @@ -324,6 +329,10 @@ function main() { HWLAT_TEST=1 echo_info "Will compile hw latency test program" shift;; + --verbose-ci) + VERBOSE_CI=1 + echo_info "Will compile with verbose instructions in CI Docker env" + shift;; --verbose-compile) VERBOSE_COMPILE=1 echo_info "Will compile with verbose instructions" @@ -416,6 +425,9 @@ function main() { CMAKE_CMD="$CMAKE_CMD -GNinja" MAKE_CMD=ninja shift;; + --sanitize-address | -fsanitize=address) + SANITIZE_ADDRESS=True + shift;; --ittiSIM) ittiSIM=1 ITTI_SIM="True" @@ -604,6 +616,7 @@ function main() { 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 "set ( SANITIZE_ADDRESS $SANITIZE_ADDRESS )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$build_dir/build eval $CMAKE_CMD @@ -936,12 +949,30 @@ function main() { echo_info "Building transport protocol libraries" rm -f liboai_transpro.so rm -f $dbin/liboai_transpro.so - compilations \ - $build_dir oai_eth_transpro \ - liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL - ln -sf liboai_eth_transpro.so liboai_transpro.so - ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so - echo_info "liboai_transpro.so is linked to ETHERNET transport" + if [ "$TP" == "Ethernet" ]; then + compilations \ + $build_dir oai_eth_transpro \ + liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL + ln -sf liboai_eth_transpro.so liboai_transpro.so + ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so + echo_info "liboai_transpro.so is linked to ETHERNET transport" + fi + if [ "$TP" == "benetel4g" ]; then + compilations \ + $build_dir benetel_4g \ + libbenetel_4g.so $dbin/libbenetel_4g.$REL + ln -sf libbenetel_4g.so liboai_transpro.so + ln -sf $dbin/libbenetel_4g.so.$REL $dbin/liboai_transpro.so + echo_info "liboai_transpro.so is linked to BENETEL4G transport" + fi + if [ "$TP" == "benetel5g" ]; then + compilations \ + $build_dir benetel_5g \ + libbenetel_5g.so $dbin/libbenetel_5g.$REL + ln -sf libbenetel_5g.so liboai_transpro.so + ln -sf $dbin/libbenetel_5g.so.$REL $dbin/liboai_transpro.so + echo_info "liboai_transpro.so is linked to BENETEL4G transport" + fi fi fi diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 674d4a0cac..9b8363fc2b 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -41,7 +41,7 @@ KERNEL_VERSION=$(uname -r | cut -d '.' -f1) KERNEL_MAJOR=$(uname -r | cut -d '.' -f2) #check if we run inside a container -IS_CONTAINER=`egrep -c "docker|podman|kubepods" /proc/self/cgroup || true` +IS_CONTAINER=`egrep -c "docker|podman|kubepods|libpod|buildah" /proc/self/cgroup || true` #sudo is not needed when we are root if [ "$UID" = 0 ] then @@ -221,6 +221,11 @@ compilations() { ret=$? } > $dlog/$2.$REL.txt 2>&1 set -e + if [ "$VERBOSE_CI" == "1" ]; then + echo_info "====== Start of log for $2.$REL.txt ======" + cat $dlog/$2.$REL.txt + echo_info "====== End of log for $2.$REL.txt ======" + fi if [[ $ret -ne 0 ]]; then check_warnings "$dlog/$2.$REL.txt" check_errors "$dlog/$2.$REL.txt" @@ -273,6 +278,10 @@ install_protobuf_from_source(){ make -j`nproc` $SUDO make install $SUDO ldconfig + if [[ -v CI_ENV ]]; then + cd /tmp + $SUDO rm -rf protobuf* + fi ) >& $protobuf_install_log } @@ -295,6 +304,10 @@ install_protobuf_c_from_source(){ make -j`nproc` $SUDO make install $SUDO ldconfig + if [[ -v CI_ENV ]]; then + cd /tmp + $SUDO rm -rf protobuf* + fi ) >& $protobuf_c_install_log } @@ -351,10 +364,10 @@ check_install_usrp_uhd_driver(){ elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then if [ $IS_CONTAINER -eq 0 ] then - $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake + $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 $INSTALLER -y install boost boost-devel $CMAKE $SUDO pip3 install mako requests fi if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then @@ -480,7 +493,7 @@ install_soapy_from_source(){ #git checkout tags/release_003_010_001_001 mkdir -p build cd build - cmake ../ + $CMAKE ../ echo "Compiling SoapyRemote" make -j`nproc` $SUDO make install @@ -499,7 +512,7 @@ install_soapy_iris_from_source(){ cd sklk-soapyiris mkdir -p build cd build - cmake ../ + $CMAKE ../ echo "Compiling SoapyIris" make -j`nproc` $SUDO make install @@ -676,7 +689,7 @@ check_install_oai_software() { automake \ bison \ build-essential \ - cmake \ + $CMAKE \ cmake-curses-gui \ ninja-build \ doxygen \ @@ -831,6 +844,9 @@ install_asn1c_from_source(){ $SUDO make install cd - $SUDO ldconfig + if [[ -v CI_ENV ]]; then + $SUDO rm -rf /tmp/asn1c + fi ) > $asn1_install_log 2>&1 } diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index 61a3984347..740c6e240b 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -43,7 +43,7 @@ #include "config_userapi.h" #include "../utils/LOG/log.h" #define CONFIG_SHAREDLIBFORMAT "libparams_%s.so" - +#include "nfapi/oai_integration/vendor_ext.h" int load_config_sharedlib(configmodule_interface_t *cfgptr) { void *lib_handle; @@ -331,9 +331,10 @@ void end_configmodule(void) { printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); for(int i=0; inumptrs ; i++) { - if (cfgptr->ptrs[i] != NULL) { + if (cfgptr->ptrs[i] != NULL && cfgptr->ptrsAllocated[i] == true) { free(cfgptr->ptrs[i]); cfgptr->ptrs[i]=NULL; + cfgptr->ptrsAllocated[i] = false; } } diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index d0309c62c3..8baaa99bb8 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -36,6 +36,8 @@ #include #include +#include +#include #include "common/config/config_paramdesc.h" #include "common/utils/T/T.h" #define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O :P1:P2... @@ -74,6 +76,7 @@ typedef struct configmodule_interface { uint32_t numptrs; uint32_t rtflags; char *ptrs[CONFIG_MAX_ALLOCATEDPTRS]; + bool ptrsAllocated[CONFIG_MAX_ALLOCATEDPTRS]; } configmodule_interface_t; #ifdef CONFIG_LOADCONFIG_MAIN diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 33d6408828..af70cae71e 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -62,6 +62,7 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) { config_get_if()->ptrs[config_get_if()->numptrs] = (char *)ptr; + config_get_if()->ptrsAllocated[config_get_if()->numptrs] = true; config_get_if()->numptrs++; } } else { @@ -82,7 +83,9 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { } if (*ptr == NULL) { - *ptr = malloc(length>40?length:40); // LTS: dummy fix, waiting Francois full fix in 4G branch + *ptr = malloc(length>40?length:40); + // LTS: dummy fix, waiting Francois full fix in 4G branch + // the issue is we don't know at this point the size we will get if ( *ptr != NULL) { memset(*ptr,0,length); diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c index 2e9fd614c5..eb08a70183 100644 --- a/common/config/libconfig/config_libconfig.c +++ b/common/config/libconfig/config_libconfig.c @@ -346,6 +346,7 @@ int config_libconfig_init(char *cfgP[], int numP) { libconfig_privdata.configfile = strdup((char *)cfgP[0]); config_get_if()->numptrs=0; memset(config_get_if()->ptrs,0,sizeof(void *) * CONFIG_MAX_ALLOCATEDPTRS); + memset(config_get_if()->ptrsAllocated, 0, sizeof(config_get_if()->ptrsAllocated)); /* Read the file. If there is an error, report it and exit. */ if(! config_read_file(&(libconfig_privdata.cfg), libconfig_privdata.configfile)) { diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 2340c78bf1..4e6ec9d3db 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -88,17 +88,20 @@ int write_file_matlab(const char *fname, void *data, int length, int dec, - char format) + unsigned int format, + int multiVec) { FILE *fp=NULL; int i; + AssertFatal((format&~MATLAB_RAW) <16,""); + if (data == NULL) return -1; //printf("Writing %d elements of type %d to %s\n",length,format,fname); - if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) { + if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14 || multiVec) { fp = fopen(fname,"a+"); } else if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) { fp = fopen(fname,"w+"); @@ -109,7 +112,32 @@ int write_file_matlab(const char *fname, return(-1); } - if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) + if ( (format&MATLAB_RAW) == MATLAB_RAW ) { + int sz[16]={sizeof(short), 2*sizeof(short), + sizeof(int), 2*sizeof(int), + sizeof(char), 2*sizeof(char), + sizeof(long long), + sizeof(double), 2*sizeof(double), + sizeof(unsigned char), + sizeof(short), + sizeof(short), + sizeof(short), + sizeof(short), + sizeof(short), + sizeof(short) + }; + int eltSz= sz[format&~MATLAB_RAW]; + if (dec==1) + fwrite(data, eltSz, length, fp); + else + for (i=0; idump_mask & D) -# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)/* */ +# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)/* */ /* 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 */ @@ -413,7 +432,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int # 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_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0) # 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 */ @@ -421,9 +440,10 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int #define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B /* unfiltered macros, useful for simulators or messages at init time, before log is configured */ -#define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0) +#define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0) #define LOG_UI(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0) #define LOG_UDUMPMSG(c, b, s, f, x...) do { log_dump(c, b, s, f, x) ;} while (0) /* */ +# define LOG_MM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 1);} while(0) /* @}*/ diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index bd598b48da..5bf9759933 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -302,6 +302,9 @@ const char* eurecomFunctionsNames[] = { /* PHY signals */ "ue_synch", "ue_slot_fep", + "ue_slot_fep_pdcch", + "ue_slot_fep_pbch", + "ue_slot_fep_pdsch", "ue_slot_fep_mbsfn", "ue_slot_fep_mbsfn_khz_1dot25", "ue_rrc_measurements", @@ -390,6 +393,8 @@ const char* eurecomFunctionsNames[] = { "rx_pmch", "rx_pmch_khz_1dot25", "pdsch_procedures", + "pdsch_procedures_crnti", + //"dlsch_procedures_crnti", "pdsch_procedures_si", "pdsch_procedures_p", "pdsch_procedures_ra", diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index f9f5868260..fb27c19973 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -283,6 +283,9 @@ typedef enum { /* PHY signals */ VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, + VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, + VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, + VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_MBSFN_KHZ_1DOT25, VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, @@ -371,9 +374,11 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH, VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PMCH_KHZ_1DOT25, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, + VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, + //VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PROC_C, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_CONFIG_SIB1_ENB, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_CONFIG_SIB2_ENB, diff --git a/common/utils/T/.gitignore b/common/utils/T/.gitignore index d754ff7c38..6a6e5817c5 100644 --- a/common/utils/T/.gitignore +++ b/common/utils/T/.gitignore @@ -4,6 +4,7 @@ T_IDs.h T_messages.txt.h genids tracer/enb +tracer/gnb tracer/extract_config tracer/record tracer/replay diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 7b5304b1cb..8cd86546cb 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -44,7 +44,7 @@ /* let's have 100 RBs functional for the basic simulator */ # define T_BUFFER_MAX (1024*64*2) #else -# define T_BUFFER_MAX (1024*64) +# define T_BUFFER_MAX (1024*64*2) #endif /* size of the local cache for messages (must be pow(2,something)) */ @@ -52,7 +52,7 @@ /* we don't need much space for the basic simulator */ # define T_CACHE_SIZE 1024 #else -# define T_CACHE_SIZE (8192 * 2) +# define T_CACHE_SIZE (8192) #endif /* maximum number of bytes a message can contain */ @@ -73,7 +73,7 @@ typedef struct { } T_cache_t; /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS (269) +#define VCD_NUM_FUNCTIONS (273) /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ #define VCD_NUM_VARIABLES (187) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 06ee5bf12b..91da823c61 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -89,6 +89,10 @@ ID = GNB_PHY_MIB DESC = NR MIB data GROUP = ALL:PHY:GNB:WIRESHARK FORMAT = int,gNB_ID : int,frame : int,slot : buffer,data +ID = GNB_PHY_PUCCH_PUSCH_IQ + DESC = gNodeB input data in the frequency domain for a slot where some PUCCH or PUSCH detection was done + GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB + FORMAT = int,frame : int,slot : buffer,rxdataF #MAC logs ID = ENB_MAC_UE_DL_SDU @@ -2403,6 +2407,21 @@ ID = VCD_FUNCTION_UE_SLOT_FEP GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value VCD_NAME = ue_slot_fep +ID = VCD_FUNCTION_UE_SLOT_FEP_PDCCH + DESC = VCD function UE_SLOT_FEP_PDCCH + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = ue_slot_fep_pdcch +ID = VCD_FUNCTION_UE_SLOT_FEP_PBCH + DESC = VCD function UE_SLOT_FEP_PBCH + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = ue_slot_fep_pbch +ID = VCD_FUNCTION_UE_SLOT_FEP_PDSCH + DESC = VCD function UE_SLOT_FEP_PDSCH + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = ue_slot_fep_pdsch ID = VCD_FUNCTION_UE_SLOT_FEP_MBSFN DESC = VCD function UE_SLOT_FEP_MBSFN GROUP = ALL:VCD:UE:VCD_FUNCTION @@ -2843,6 +2862,11 @@ ID = VCD_FUNCTION_PDSCH_PROC GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value VCD_NAME = pdsch_procedures +ID = VCD_FUNCTION_PDSCH_PROC_C + DESC = VCD function PDSCH_PROC_C + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = pdsch_procedures_crnti ID = VCD_FUNCTION_PDSCH_PROC_SI DESC = VCD function PDSCH_PROC_SI GROUP = ALL:VCD:UE:VCD_FUNCTION diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 792c2a407c..0713d9a3df 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -7,7 +7,8 @@ LIBS=-lm XLIBS=-lX11 -lpng -lXft all: record replay extract_config textlog enb ue vcd macpdu2wireshark \ - extract_input_subframe extract_output_subframe to_vcd extract multi + extract_input_subframe extract_output_subframe to_vcd extract multi \ + gnb record: utils.o record.o database.o config.o $(CC) $(CFLAGS) -o record $^ $(LIBS) @@ -60,6 +61,11 @@ macpdu2wireshark: macpdu2wireshark.o database.o utils.o handler.o event.o \ multi: multi.o utils.o database.o config.o $(CC) $(CFLAGS) -o multi $^ $(LIBS) +gnb: utils.o gnb.o database.o event.o handler.o config.o \ + view/view.a gui/gui.a logger/logger.a \ + filter/filter.a + $(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS) + multi.o: ../T_IDs.h ../T_IDs.h: @@ -85,7 +91,7 @@ filter/filter.a: clean: rm -f *.o core tracer_remote textlog enb ue vcd record replay rm -f extract_config macpdu2wireshark extract_input_subframe - rm -f extract_output_subframe to_vcd extract multi + rm -f extract_output_subframe to_vcd extract multi gnb cd gui && $(MAKE) clean cd view && $(MAKE) clean cd logger && $(MAKE) clean diff --git a/common/utils/T/tracer/gnb.c b/common/utils/T/tracer/gnb.c new file mode 100644 index 0000000000..4aaa4898a1 --- /dev/null +++ b/common/utils/T/tracer/gnb.c @@ -0,0 +1,172 @@ +#include +#include +#include +#include +#include +#include "database.h" +#include "handler.h" +#include "config.h" +#include "logger/logger.h" +#include "view/view.h" +#include "gui/gui.h" + +typedef struct { + widget *pucch_pusch_iq_plot; + logger *pucch_pusch_iq_logger; +} gnb_gui; + +typedef struct { + int socket; + int *is_on; + int nevents; + pthread_mutex_t lock; + gnb_gui *e; + void *database; +} gnb_data; + +void is_on_changed(void *_d) +{ + gnb_data *d = _d; + char t; + + if (pthread_mutex_lock(&d->lock)) abort(); + + if (d->socket == -1) goto no_connection; + + t = 1; + if (socket_send(d->socket, &t, 1) == -1 || + socket_send(d->socket, &d->nevents, sizeof(int)) == -1 || + socket_send(d->socket, d->is_on, d->nevents * sizeof(int)) == -1) + goto connection_dies; + +no_connection: + if (pthread_mutex_unlock(&d->lock)) abort(); + return; + +connection_dies: + close(d->socket); + d->socket = -1; + if (pthread_mutex_unlock(&d->lock)) abort(); +} + +void usage(void) +{ + printf( +"options:\n" +" -d this option is mandatory\n" +" -ip connect to given IP address (default %s)\n" +" -p connect to given port (default %d)\n", + DEFAULT_REMOTE_IP, + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +static void *gui_thread(void *_g) +{ + gui *g = _g; + gui_loop(g); + return NULL; +} + +static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database, + gnb_data *ed) +{ + widget *main_window; + widget *top_container; + widget *line; + widget *w; + logger *l; + view *v; + + main_window = new_toplevel_window(g, 500, 300, "gNB tracer"); + + top_container = new_container(g, VERTICAL); + widget_add_child(g, main_window, top_container, -1); + + line = new_container(g, HORIZONTAL); + widget_add_child(g, top_container, line, -1); + + /* PUCCH/PUSCH IQ data */ + w = new_xy_plot(g, 55, 55, "", 50); + e->pucch_pusch_iq_plot = w; + widget_add_child(g, line, w, -1); + xy_plot_set_range(g, w, -1000, 1000, -1000, 1000); + xy_plot_set_title(g, w, "rxdataF"); + l = new_iqlog_full(h, database, "GNB_PHY_PUCCH_PUSCH_IQ", "rxdataF"); + v = new_view_xy(300*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE); + logger_add_view(l, v); + e->pucch_pusch_iq_logger = l; +} + +int main(int n, char **v) +{ + char *database_filename = NULL; + void *database; + char *ip = DEFAULT_REMOTE_IP; + int port = DEFAULT_REMOTE_PORT; + int *is_on; + int number_of_events; + int i; + event_handler *h; + gnb_data gnb_data; + gui *g; + gnb_gui eg; + + 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; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(database_filename); + + load_config_file(database_filename); + + number_of_events = number_of_ids(database); + is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) abort(); + + h = new_handler(database); + + on_off(database, "GNB_PHY_PUCCH_PUSCH_IQ", is_on, 1); + + gnb_data.database = database; + gnb_data.socket = -1; + gnb_data.is_on = is_on; + gnb_data.nevents = number_of_events; + if (pthread_mutex_init(&gnb_data.lock, NULL)) abort(); + + g = gui_init(); + new_thread(gui_thread, g); + + gnb_main_gui(&eg, g, h, database, &gnb_data); + + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + +restart: + clear_remote_config(); + if (gnb_data.socket != -1) close(gnb_data.socket); + gnb_data.socket = connect_to(ip, port); + + /* send the first message - activate selected traces */ + is_on_changed(&gnb_data); + + /* read messages */ + while (1) { + event e; + e = get_event(gnb_data.socket, &ebuf, database); + if (e.type == -1) goto restart; + if (pthread_mutex_lock(&gnb_data.lock)) abort(); + handle_event(h, e); + if (pthread_mutex_unlock(&gnb_data.lock)) abort(); + } + + return 0; +} diff --git a/common/utils/T/tracer/logger/iqlog.c b/common/utils/T/tracer/logger/iqlog.c index 168c50e39b..1947de2bca 100644 --- a/common/utils/T/tracer/logger/iqlog.c +++ b/common/utils/T/tracer/logger/iqlog.c @@ -74,6 +74,44 @@ static void _event(void *p, event e) l->common.v[i]->append(l->common.v[i], l->i, l->q, count); } +static void _event_full(void *p, event e) +{ + struct iqlog *l = p; + int i; + void *buffer; + int bsize; + int nsamples; + float *idst, *qdst; + + if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0) + return; + + buffer = e.e[l->buffer_arg].b; + bsize = e.e[l->buffer_arg].bsize; + + nsamples = bsize / 4; + + if (nsamples > l->max_length) { + l->i = realloc(l->i, nsamples * sizeof(float)); + if (l->i == NULL) abort(); + l->q = realloc(l->q, nsamples * sizeof(float)); + if (l->q == NULL) abort(); + l->max_length = nsamples; + } + + idst = l->i; + qdst = l->q; + for (i = 0; i < nsamples; i++) { + *idst = ((int16_t *)buffer)[i * 2]; + *qdst = ((int16_t *)buffer)[i * 2 + 1]; + idst++; + qdst++; + } + + for (i = 0; i < l->common.vsize; i++) + l->common.v[i]->append(l->common.v[i], l->i, l->q, nsamples); +} + logger *new_iqlog(event_handler *h, void *database, char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti, char *buffer_varname) @@ -149,3 +187,43 @@ logger *new_iqlog(event_handler *h, void *database, return ret; } + +logger *new_iqlog_full(event_handler *h, void *database, char *event_name, + char *buffer_varname) +{ + struct iqlog *ret; + int event_id; + database_event_format f; + int i; + + ret = calloc(1, sizeof(struct iqlog)); if (ret == NULL) abort(); + + ret->common.event_name = strdup(event_name); + if (ret->common.event_name == NULL) abort(); + ret->database = database; + + event_id = event_id_from_name(database, event_name); + + ret->common.handler_id = register_handler_function(h, event_id, _event_full, + ret); + + f = get_format(database, event_id); + + /* look for args */ + ret->buffer_arg = -1; + for (i = 0; i < f.count; i++) { + if (!strcmp(f.name[i], buffer_varname)) ret->buffer_arg = i; + } + if (ret->buffer_arg == -1) { + printf("%s:%d: buffer argument '%s' not found in event '%s'\n", + __FILE__, __LINE__, buffer_varname, event_name); + abort(); + } + if (strcmp(f.type[ret->buffer_arg], "buffer") != 0) { + printf("%s:%d: argument '%s' has wrong type (should be 'buffer')\n", + __FILE__, __LINE__, buffer_varname); + abort(); + } + + return ret; +} diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index 7c019b4797..d746161e70 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -23,6 +23,8 @@ logger *new_ticklog(void *event_handler, void *database, logger *new_iqlog(void *event_handler, void *database, char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti, char *buffer_varname); +logger *new_iqlog_full(void *event_handler, void *database, char *event_name, + char *buffer_varname); logger *new_iqdotlog(void *event_handler, void *database, char *event_name, char *I, char *Q); diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 5f07fc00aa..0671aed813 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -32,6 +32,81 @@ #include #include "assertions.h" +#include "nr_common.h" + +// 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}, + {3, 1710000, 1785000, 1805000, 1880000, 20, 361000, 100}, + {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, 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}, + {74, 1427000, 1470000, 1475000, 1518000, 20, 295000, 100}, + {75, 000, 000, 1432000, 1517000, 20, 286400, 100}, + {76, 000, 000, 1427000, 1432000, 20, 285400, 100}, + {77, 3300000, 4200000, 3300000, 4200000, 1, 620000, 15}, + {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, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15}, + {79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30}, + {80, 1710000, 1785000, 000, 000, 20, 342000, 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}, + {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} +}; + +const size_t nr_bandtable_size = sizeof(nr_bandtable) / sizeof(nr_bandentry_t); int NRRIV2BW(int locationAndBandwidth,int N_RB) { int tmp = locationAndBandwidth/N_RB; diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 5601c0fcbf..6389c2c094 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -36,6 +36,20 @@ #include #include "assertions.h" +typedef struct nr_bandentry_s { + int16_t band; + uint64_t ul_min; + uint64_t ul_max; + uint64_t dl_min; + uint64_t dl_max; + uint64_t step_size; + uint64_t N_OFFs_DL; + uint8_t deltaf_raster; +} nr_bandentry_t; + +extern const size_t nr_bandtable_size; +extern nr_bandentry_t nr_bandtable[]; + int NRRIV2BW(int locationAndBandwidth,int N_RB); int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB); int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize); diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index 2189be9fe8..c774da57e6 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -339,7 +339,9 @@ extern "C" { 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)),""); + task_list_t **new_tasks = (task_list_t **)realloc(tasks, nb_queues * sizeof(*tasks)); + AssertFatal(new_tasks != NULL, "could not realloc() tasks list"); + tasks = new_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); diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index d13b193ff9..8d84646e07 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -132,9 +132,9 @@ 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 +## 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. +The sa flag is used to run gNB in standalone mode. Currently OAI in NR standalone mode transmits and receives SIB1 and triggers the RA procedure for initial access. In order to run gNB in standalone mode, the following flag is needed at gNB: @@ -147,8 +147,9 @@ At the gNB the --sa flag does the following - 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. +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 +- After the successful decoding of a SIB1 at RRC, the UE will start the 5G NR Initial Access Procedure by triggering the RA procedure. From the `cmake_targets/ran_build/build` folder: @@ -168,7 +169,7 @@ With the RF simulator (on the same machine): ## 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. +The -C and --CO flags can be used together at UE side to set custom downlink and uplink FR1 arbitrary frequencies for the IF equipment. In order to run this setup, the following flags are needed at the UE side: @@ -182,9 +183,11 @@ and the following parameters must be configured in the RUs section of the gNB co `if_offset` -### Run OAI with custom DL/UL intermediate frequencies +The values must be given in Hz. -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. +### Run OAI with custom DL/UL arbitrary frequencies + +The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 (FDD) at gNB side. From the `cmake_targets/ran_build/build` folder: diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index 610cc5bdd4..5f9299f0ef 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -30,8 +30,6 @@ http://www.saelig.com/MFR00066/ste2300.htm ## Configuration Overview * Non Standalone (NSA) configuration : initial Control Plane established between UE and RAN eNB, then User Plane established between UE and gNB, Core network is 4G based supporting rel 15 - -* Commercial UE: Oppo Reno 5G * OAI Software Defined gNB and eNB * eNB RF front end: USRP (ETTUS) B200 Mini or B210 * gNB RF front end: USRP (ETTUS) B200 Mini or B210 (N310 will be needed for MIMO and wider BW's) @@ -40,6 +38,18 @@ http://www.saelig.com/MFR00066/ste2300.htm * BW: 40MHz * Antenna scheme: SISO +## COTS UEs + +Our code might not work with all 5G phones yet, but we are constantly improving it. Here is a list of COTS UEs that we know that work with OAI. + +* Oppo Reno 5G +* Samsung A90 5G +* Google Pixel 5G (note1) +* Simcom SIMCOM8200EA +* Quectel RM500Q-GL + +Note1: In the version we have at Eurecom, you need to set the PLMN to 50501, and you also need to change the firmware to "11.0.0 (RD1A.201105.003.B1, Nov 2020, EU carriers)" (see https://developers.google.com/android/images) + ## Repository https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop diff --git a/docker/Dockerfile.eNB.rhel8.2 b/docker/Dockerfile.eNB.rhel8.2 index 5fcd5a7b9f..aa8b9aa228 100644 --- a/docker/Dockerfile.eNB.rhel8.2 +++ b/docker/Dockerfile.eNB.rhel8.2 @@ -27,14 +27,15 @@ FROM localhost/ran-build:latest AS enb-build +RUN rm -Rf /oai-ran WORKDIR /oai-ran +COPY . . #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 + ./build_oai --eNB --ninja -w USRP --verbose-ci # debug #RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-softmodem.Rel15 diff --git a/docker/Dockerfile.eNB.ubuntu18 b/docker/Dockerfile.eNB.ubuntu18 index cdfb37ebfc..95d7194c31 100644 --- a/docker/Dockerfile.eNB.ubuntu18 +++ b/docker/Dockerfile.eNB.ubuntu18 @@ -27,14 +27,15 @@ FROM ran-build:latest AS enb-build +RUN rm -Rf /oai-ran WORKDIR /oai-ran +COPY . . #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 + ./build_oai --eNB --ninja -w USRP --verbose-ci RUN apt-get install -y python3-pip && \ pip3 install --ignore-installed pyyaml && \ diff --git a/docker/Dockerfile.gNB.rhel8.2 b/docker/Dockerfile.gNB.rhel8.2 index fb9ade927f..6969c691fd 100644 --- a/docker/Dockerfile.gNB.rhel8.2 +++ b/docker/Dockerfile.gNB.rhel8.2 @@ -27,14 +27,15 @@ FROM localhost/ran-build:latest AS gnb-build +RUN rm -Rf /oai-ran WORKDIR /oai-ran +COPY . . #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 + ./build_oai --gNB --ninja -w USRP --verbose-ci #debug #RUN ldconfig -v diff --git a/docker/Dockerfile.gNB.ubuntu18 b/docker/Dockerfile.gNB.ubuntu18 index d43ad4709d..276d6989c4 100644 --- a/docker/Dockerfile.gNB.ubuntu18 +++ b/docker/Dockerfile.gNB.ubuntu18 @@ -27,14 +27,15 @@ FROM ran-build:latest AS gnb-build +RUN rm -Rf /oai-ran WORKDIR /oai-ran +COPY . . #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 + ./build_oai --gNB --ninja -w USRP --verbose-ci #debug RUN ldconfig -v diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2 index 0a853dcd6b..e22343d63c 100644 --- a/docker/Dockerfile.lteUE.rhel8.2 +++ b/docker/Dockerfile.lteUE.rhel8.2 @@ -27,15 +27,15 @@ FROM localhost/ran-build:latest AS lte-ue-build - +RUN rm -Rf /oai-ran WORKDIR /oai-ran +COPY . . #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 + ./build_oai --UE --ninja -w USRP --verbose-ci # debug #RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-uesoftmodem.Rel15 diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18 index 8793cc54f7..6af2e61991 100644 --- a/docker/Dockerfile.lteUE.ubuntu18 +++ b/docker/Dockerfile.lteUE.ubuntu18 @@ -27,14 +27,15 @@ FROM ran-build:latest AS lte-ue-build +RUN rm -Rf /oai-ran WORKDIR /oai-ran +COPY . . #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 + ./build_oai --UE --ninja -w USRP --verbose-ci # debug #RUN ldconfig -v diff --git a/docker/Dockerfile.nrUE.rhel8.2 b/docker/Dockerfile.nrUE.rhel8.2 index f9f3f8e4bf..01988fd6ff 100644 --- a/docker/Dockerfile.nrUE.rhel8.2 +++ b/docker/Dockerfile.nrUE.rhel8.2 @@ -27,14 +27,15 @@ FROM localhost/ran-build:latest AS nr-ue-build +RUN rm -Rf /oai-ran WORKDIR /oai-ran +COPY . . #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 + ./build_oai --nrUE --ninja -w USRP --verbose-ci # debug #RUN ldconfig -v diff --git a/docker/Dockerfile.nrUE.ubuntu18 b/docker/Dockerfile.nrUE.ubuntu18 index 5450194f35..c96bcf80ef 100644 --- a/docker/Dockerfile.nrUE.ubuntu18 +++ b/docker/Dockerfile.nrUE.ubuntu18 @@ -27,14 +27,15 @@ FROM ran-build:latest AS nr-ue-build +RUN rm -Rf /oai-ran WORKDIR /oai-ran +COPY . . #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 + ./build_oai --nrUE --ninja -w USRP --verbose-ci # debug #RUN ldconfig -v diff --git a/executables/main-ocp.c b/executables/main-ocp.c index a9080f6417..c77b00febf 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -74,6 +74,7 @@ int config_sync_var=-1; volatile int oai_exit = 0; double cpuf; uint16_t sf_ahead=4; +//uint16_t slot_ahead=6; int otg_enabled; uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 4a655dfc57..a92f433560 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -81,10 +81,11 @@ #include "s1ap_eNB.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" - +#include #include "T.h" - +#include "nfapi/oai_integration/vendor_ext.h" +#include //#define DEBUG_THREADS 1 //#define USRP_DEBUG 1 @@ -92,17 +93,6 @@ // extern openair0_device openair0; -extern volatile int start_gNB; -extern volatile int start_UE; -extern volatile int oai_exit; - -extern openair0_config_t openair0_cfg[MAX_CARDS]; - -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 @@ -111,39 +101,43 @@ 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 -/* mutex, cond and variable to serialize phy proc TX calls - * (this mechanism may be relaxed in the future for better - * performances) - */ -static struct { - pthread_mutex_t mutex_phy_proc_tx; - pthread_cond_t cond_phy_proc_tx; - volatile uint8_t phy_proc_CC_id; -} sync_phy_proc; -extern double cpuf; - -void init_gNB(int,int); -void stop_gNB(int nb_inst); - -int wakeup_txfh(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int frame_tx, int slot_tx, uint64_t timestamp_tx); -int wakeup_tx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, uint64_t timestamp_tx); #include "executables/thread-common.h" -//extern PARALLEL_CONF_t get_thread_parallel_conf(void); -//extern WORKER_CONF_t get_thread_worker_conf(void); -void wakeup_prach_gNB(PHY_VARS_gNB *gNB, RU_t *ru, int frame, int subframe); - -extern uint8_t nfapi_mode; -extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); -extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); - //#define TICK_TO_US(ts) (ts.diff) #define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials) -static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) { +void tx_func(void *param) { + + processingData_L1_t *info = (processingData_L1_t *) param; + PHY_VARS_gNB *gNB = info->gNB; + int frame_tx = info->frame_tx; + int slot_tx = info->slot_tx; + + phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); + + // start FH TX processing + notifiedFIFO_elt_t *res; + res = pullTpool(gNB->resp_RU_tx, gNB->threadPool); + processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res); + syncMsg->frame_tx = frame_tx; + syncMsg->slot_tx = slot_tx; + syncMsg->timestamp_tx = info->timestamp_tx; + syncMsg->ru = gNB->RU_list[0]; + res->key = slot_tx; + pushTpool(gNB->threadPool, res); +} + +void rx_func(void *param) { + + processingData_L1_t *info = (processingData_L1_t *) param; + PHY_VARS_gNB *gNB = info->gNB; + int frame_rx = info->frame_rx; + int slot_rx = info->slot_rx; + int frame_tx = info->frame_tx; + int slot_tx = info->slot_tx; sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; @@ -151,13 +145,14 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t // ******************************************************************* // NFAPI not yet supported for NR - this code has to be revised - if (nfapi_mode == 1) { + 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(frame_rx, slot_rx); + // oai_subframe_ind(frame_rx, slot_rx); + oai_slot_ind(frame_rx, slot_rx); stop_meas(&nfapi_meas); /*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus|| @@ -233,12 +228,6 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t rnti_to_remove_count = 0; if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1); - /* - // if this is IF5 or 3GPP_gNB - if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) { - wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx); - } - */ // Call the scheduler pthread_mutex_lock(&gNB->UL_INFO_mutex); @@ -261,33 +250,35 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t 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); - } - - 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) { - - if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) { - phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); + for (int 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); } + phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); } stop_meas( &softmodem_stats_rxtx_sf ); LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx); + + notifiedFIFO_elt_t *res; + + if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { + res = pullTpool(gNB->resp_L1_tx, gNB->threadPool); + processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res); + syncMsg->gNB = gNB; + syncMsg->frame_rx = frame_rx; + syncMsg->slot_rx = slot_rx; + syncMsg->frame_tx = frame_tx; + syncMsg->slot_tx = slot_tx; + syncMsg->timestamp_tx = info->timestamp_tx; + res->key = slot_tx; + pushTpool(gNB->threadPool, res); + } + #if 0 LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now, @@ -327,466 +318,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t TICK_TO_US(gNB->ulsch_tc_intl2_stats) ); #endif - return(0); } - -static void *gNB_L1_thread_tx(void *param) { - PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param; - gNB_L1_proc_t *gNB_proc = &gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB_proc->L1_proc_tx; - //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; - char thread_name[100]; - - sprintf(thread_name,"gNB_L1_thread_tx\n"); - - while (!oai_exit) { - if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->instance_cnt,thread_name)<0) break; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 ); - - if (oai_exit) break; - - // ***************************************** - // TX processing for subframe n+4 - // 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) - // ***************************************** - int frame_tx = L1_proc_tx->frame_tx; - int slot_tx = L1_proc_tx->slot_tx; - uint64_t timestamp_tx = L1_proc_tx->timestamp_tx; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx); - phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 1 ); - pthread_mutex_lock( &L1_proc_tx->mutex ); - L1_proc_tx->instance_cnt = -1; - - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc_tx->cond) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - } - pthread_mutex_unlock(&L1_proc_tx->mutex); - - wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 0 ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); - } - - return 0; -} - -/*! - * \brief The RX UE-specific and TX thread of gNB. - * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ - -static void *gNB_L1_thread( void *param ) { - static int gNB_thread_rxtx_status; - PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param; - gNB_L1_proc_t *gNB_proc = &gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc; - //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id]; - char thread_name[100]; - // set default return value - // set default return value - gNB_thread_rxtx_status = 0; - - sprintf(thread_name,"gNB_L1_thread"); - - - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 ); - if (wait_on_condition(&L1_proc->mutex,&L1_proc->cond,&L1_proc->instance_cnt,thread_name)<0) break; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 ); - - int frame_rx = L1_proc->frame_rx; - int slot_rx = L1_proc->slot_rx; - int frame_tx = L1_proc->frame_tx; - int slot_tx = L1_proc->slot_tx; - uint64_t timestamp_tx = L1_proc->timestamp_tx; - - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,slot_rx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,frame_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,frame_rx); - - if (oai_exit) break; - - if (gNB->CC_id==0) { - if (rxtx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,thread_name) < 0) break; - } - - if (release_thread(&L1_proc->mutex,&L1_proc->instance_cnt,thread_name)<0) break; - - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,timestamp_tx); - else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(gNB,L1_proc,frame_tx,slot_tx,timestamp_tx); - } // while !oai_exit - - LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n"); - gNB_thread_rxtx_status = 0; - return &gNB_thread_rxtx_status; -} - - -#if 0 -// Wait for gNB application initialization to be complete (gNB registration to MME) -static void wait_system_ready (char *message, volatile int *start_flag) { - static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....", - " ....", " ...", " ..", " .", " " - }; - int i = 0; - - while ((!oai_exit) && (*start_flag == 0)) { - LOG_N(EMU, message, indicator[i]); - fflush(stdout); - i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0])); - usleep(200000); - } - - LOG_D(EMU,"\n"); -} -#endif - - - - - -void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru) { - gNB_L1_proc_t *proc = &gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - RU_proc_t *ru_proc=&ru->proc; - proc->frame_rx = frame_rx; - proc->slot_rx = slot_rx; - sl_ahead = sf_ahead*fp->slots_per_subframe; - - if (!oai_exit) { - T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx)); - L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); - L1_proc->frame_rx = ru_proc->frame_rx; - L1_proc->slot_rx = ru_proc->tti_rx; - L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; - L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; - - if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id); - - ru_proc->timestamp_tx = L1_proc->timestamp_tx; - ru_proc->tti_tx = L1_proc->slot_tx; - ru_proc->frame_tx = L1_proc->frame_tx; - } -} - -int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx) { - - RU_t *ru; - RU_proc_t *ru_proc; - - int waitret = 0, ret = 0, time_ns = 1000*1000; - struct timespec now, abstime; - // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time - // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1); - time_ns = time_ns/gNB->frame_parms.slots_per_subframe; - AssertFatal((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); - while (proc->instance_cnt_RUs < 0) { - clock_gettime(CLOCK_REALTIME, &now); - abstime.tv_sec = now.tv_sec; - abstime.tv_nsec = now.tv_nsec + time_ns; - - if (abstime.tv_nsec >= 1000*1000*1000) { - abstime.tv_nsec -= 1000*1000*1000; - abstime.tv_sec += 1; - } - if((waitret = pthread_cond_timedwait(&proc->cond_RUs,&proc->mutex_RUs_tx,&abstime)) == 0) break; // this unlocks mutex_rxtx while waiting and then locks it again - } - proc->instance_cnt_RUs = -1; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); - AssertFatal((ret = pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0); - - if (waitret == ETIMEDOUT) { - LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx); - - AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); - gNB->proc.RU_mask_tx = 0; - AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); - AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); - proc->instance_cnt_RUs = 0; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); - AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0); - - return(-1); - } - - for(int i=0; inum_RU; i++) - { - ru = gNB->RU_list[i]; - ru_proc = &ru->proc; - - - if (ru_proc->instance_cnt_gNBs == 0) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1); - LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->slot_rx); - AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); - gNB->proc.RU_mask_tx = 0; - AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0); - return(-1); - } - AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); - - ru_proc->instance_cnt_gNBs = 0; - ru_proc->timestamp_tx = timestamp_tx; - ru_proc->tti_tx = slot_tx; - ru_proc->frame_tx = frame_tx; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs); - - LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx); - // the thread can now be woken up - AssertFatal(pthread_cond_signal(&ru_proc->cond_gNBs) == 0, - "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n"); - AssertFatal((ret=pthread_mutex_unlock(&ru_proc->mutex_gNBs))==0,"mutex_unlock returned %d\n",ret); - - } - return(0); -} - -int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx) { - - - gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx; - - int ret; - - - AssertFatal((ret = pthread_mutex_lock(&L1_proc_tx->mutex))==0,"mutex_lock returns %d\n",ret); - - - while(L1_proc_tx->instance_cnt == 0) { - pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex); - } - - L1_proc_tx->instance_cnt = 0; - - - L1_proc_tx->slot_rx = slot_rx; - L1_proc_tx->frame_rx = frame_rx; - L1_proc_tx->slot_tx = slot_tx; - L1_proc_tx->frame_tx = frame_tx; - L1_proc_tx->timestamp_tx = timestamp_tx; - - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0); - // the thread can now be woken up - // the thread can now be woken up - AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for gNB L1 thread\n"); - - AssertFatal((ret=pthread_mutex_unlock(&L1_proc_tx->mutex))==0,"mutex_unlock returns %d\n",ret); - - return(0); -} - -int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { - gNB_L1_proc_t *proc=&gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc=&proc->L1_proc; - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - RU_proc_t *ru_proc=&ru->proc; - int ret; - int i; - struct timespec abstime; - int time_ns = 50000; - int wait_timer = 0; - bool do_last_check = 1; - - AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret); - for (i=0; inum_RU; i++) { - if (ru == gNB->RU_list[i]) { - if ((proc->RU_mask&(1< 0) - LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", - gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask); - proc->RU_mask |= (1<RU_mask != (1<num_RU)-1) { // not all RUs have provided their information so return - LOG_E(PHY,"Not all RUs have provided their info\n"); - AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"mutex_unlock returns %d\n",ret); - return(0); - } - else { // all RUs have provided their information so continue on and wakeup gNB processing - proc->RU_mask = 0; - AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret); - } - - // wake up TX for subframe n+sf_ahead - // lock the TX mutex and make sure the thread is ready - while (wait_timer < 200) { - clock_gettime(CLOCK_REALTIME, &abstime); - abstime.tv_nsec = abstime.tv_nsec + time_ns; - - if (abstime.tv_nsec >= 1000*1000*1000) { - abstime.tv_nsec -= 1000*1000*1000; - abstime.tv_sec += 1; - } - - AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret); - - if (L1_proc->instance_cnt == 0) { // L1_thread is busy so wait for a bit - AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret); - wait_timer += 50; - usleep(50); - } - else { - do_last_check = 0; - break; - } - } - if (do_last_check) { - AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret); - if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe - AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret); - LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx); - return (-1); - } - } - - ++L1_proc->instance_cnt; - // 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 - // transmitted timestamp of the next TX slot (first). - - // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, - // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti, - // and proc->slot_tx = proc->slot_rx+sf_ahead - L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); - L1_proc->frame_rx = ru_proc->frame_rx; - L1_proc->slot_rx = ru_proc->tti_rx; - L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; - L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; - - LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sf_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sf_ahead); - - pthread_mutex_unlock( &L1_proc->mutex ); - - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc->cond) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } - - return(0); -} -/* -void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe) { - - gNB_L1_proc_t *proc = &gNB->proc; - LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms; - int i; - - if (ru!=NULL) { - pthread_mutex_lock(&proc->mutex_RU_PRACH); - for (i=0;inum_RU;i++) { - if (ru == gNB->RU_list[i]) { - LOG_D(PHY,"frame %d, subframe %d: RU %d for gNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,gNB->Mod_id,proc->RU_mask_prach,gNB->num_RU); - if ((proc->RU_mask_prach&(1< 0) - LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n", - gNB->Mod_id,frame,subframe,ru->idx,gNB->num_RU,proc->RU_mask_prach); - proc->RU_mask_prach |= (1<RU_mask_prach != (1<num_RU)-1) { // not all RUs have provided their information so return - pthread_mutex_unlock(&proc->mutex_RU_PRACH); - return; - } - else { // all RUs have provided their information so continue on and wakeup gNB processing - proc->RU_mask_prach = 0; - pthread_mutex_unlock(&proc->mutex_RU_PRACH); - } - } - - // check if we have to detect PRACH first - if (is_prach_subframe(fp,frame,subframe)>0) { - LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe); - if (proc->instance_cnt_prach == 0) { - LOG_W(PHY,"[gNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe); - return; - } - - // wake up thread for PRACH RX - if (pthread_mutex_lock(&proc->mutex_prach) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach); - exit_fun( "error locking mutex_prach" ); - return; - } - - ++proc->instance_cnt_prach; - // set timing for prach thread - proc->frame_prach = frame; - proc->subframe_prach = subframe; - - // the thread can now be woken up - if (pthread_cond_signal(&proc->cond_prach) != 0) { - LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB PRACH thread %d\n", proc->thread_index); - exit_fun( "ERROR pthread_cond_signal" ); - return; - } - - pthread_mutex_unlock( &proc->mutex_prach ); - } - -}*/ - -/*! - * \brief The prach receive thread of gNB. - * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -/* -static void* gNB_thread_prach( void* param ) { - static int gNB_thread_prach_status; - - - PHY_VARS_gNB *gNB= (PHY_VARS_gNB *)param; - gNB_L1_proc_t *proc = &gNB->proc; - - // set default return value - gNB_thread_prach_status = 0; - - - - while (!oai_exit) { - - if (oai_exit) break; - - - if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break; - - LOG_D(PHY,"Running gNB prach procedures\n"); - prach_procedures(gNB ,0); - - if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break; - } - - LOG_I(PHY, "Exiting gNB thread PRACH\n"); - - gNB_thread_prach_status = 0; - return &gNB_thread_prach_status; -} -*/ - -extern void init_td_thread(PHY_VARS_gNB *); -extern void init_te_thread(PHY_VARS_gNB *); - static void *process_stats_thread(void *param) { PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param; @@ -807,71 +339,13 @@ static void *process_stats_thread(void *param) { return(NULL); } - -void init_gNB_proc(int inst) { - int i=0; - int CC_id = 0; +void init_gNB_Tpool(int inst) { PHY_VARS_gNB *gNB; - gNB_L1_proc_t *proc; - gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx; -// LOG_I(PHY,"%s(inst:%d) RC.nb_nr_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_nr_CC[inst]); gNB = RC.gNB[inst]; - LOG_I(PHY,"Initializing gNB processes instance:%d CC_id %d \n",inst,CC_id); - - proc = &gNB->proc; - L1_proc = &proc->L1_proc; - 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 = CC_id; - 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); - pthread_mutex_init( &L1_proc->mutex, NULL); - pthread_mutex_init( &L1_proc_tx->mutex, NULL); - pthread_cond_init( &L1_proc->cond, NULL); - pthread_cond_init( &L1_proc_tx->cond, NULL); - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); - pthread_mutex_init( &proc->mutex_RU,NULL); - pthread_mutex_init( &proc->mutex_RU_tx,NULL); - pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_asynch_rxtx, NULL); - LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag); - - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { - threadCreate( &L1_proc->pthread, gNB_L1_thread, gNB, "L1_proc", -1, OAI_PRIORITY_RT ); - threadCreate( &L1_proc_tx->pthread, gNB_L1_thread_tx, gNB,"L1_proc_tx", -1, OAI_PRIORITY_RT); - } - - if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW); - //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB ); - char name[16]; - - if (gNB->single_thread_flag==0) { - snprintf( name, sizeof(name), "L1 %d", i ); - pthread_setname_np( L1_proc->pthread, name ); - snprintf( name, sizeof(name), "L1TX %d", i ); - pthread_setname_np( L1_proc_tx->pthread, name ); - } - - AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); - - /* setup PHY proc TX sync mechanism */ - pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); - pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); - sync_phy_proc.phy_proc_CC_id = 0; + gNB_L1_proc_t *proc = &gNB->proc; + // ULSCH decoding threadpool gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); - gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); int numCPU = sysconf(_SC_NPROCESSORS_ONLN); int threadCnt = min(numCPU, gNB->pusch_proc_threads); char ul_pool[80]; @@ -882,70 +356,40 @@ void init_gNB_proc(int inst) { s_offset += 3; } initTpool(ul_pool, gNB->threadPool, false); + // ULSCH decoder result FIFO + gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); initNotifiedFIFO(gNB->respDecode); -} + // L1 RX result FIFO + gNB->resp_L1 = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + initNotifiedFIFO(gNB->resp_L1); + + // L1 TX result FIFO + gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + initNotifiedFIFO(gNB->resp_L1_tx); + + // RU TX result FIFO + gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); + initNotifiedFIFO(gNB->resp_RU_tx); + + // Stats measurement thread + if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW); +} /*! * \brief Terminate gNB TX and RX threads. */ void kill_gNB_proc(int inst) { - int *status; PHY_VARS_gNB *gNB; - gNB_L1_proc_t *proc; - gNB_L1_rxtx_proc_t *L1_proc, *L1_proc_tx; gNB=RC.gNB[inst]; - proc = &gNB->proc; - L1_proc = &proc->L1_proc; - L1_proc_tx = &proc->L1_proc_tx; - LOG_I(PHY, "Killing TX inst %d\n",inst ); - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { - pthread_mutex_lock(&L1_proc->mutex); - L1_proc->instance_cnt = 0; - pthread_cond_signal(&L1_proc->cond); - pthread_mutex_unlock(&L1_proc->mutex); - pthread_mutex_lock(&L1_proc_tx->mutex); - L1_proc_tx->instance_cnt = 0; - pthread_cond_signal(&L1_proc_tx->cond); - pthread_mutex_unlock(&L1_proc_tx->mutex); - } - - proc->instance_cnt_prach = 0; - pthread_cond_signal( &proc->cond_prach ); - pthread_cond_signal( &proc->cond_asynch_rxtx ); - pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); - // LOG_D(PHY, "joining pthread_prach\n"); - // pthread_join( proc->pthread_prach, (void**)&status ); - LOG_I(PHY, "Destroying prach mutex/cond\n"); - pthread_mutex_destroy( &proc->mutex_prach ); - pthread_cond_destroy( &proc->cond_prach ); LOG_I(PHY, "Destroying UL_INFO mutex\n"); pthread_mutex_destroy(&gNB->UL_INFO_mutex); - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { - LOG_I(PHY, "Joining L1_proc mutex/cond\n"); - pthread_join( L1_proc->pthread, (void **)&status ); - LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n"); - pthread_join( L1_proc_tx->pthread, (void **)&status ); - } - - LOG_I(PHY, "Destroying L1_proc mutex/cond\n"); - pthread_mutex_destroy( &L1_proc->mutex ); - pthread_cond_destroy( &L1_proc->cond ); - LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n"); - pthread_mutex_destroy( &L1_proc_tx->mutex ); - pthread_cond_destroy( &L1_proc_tx->cond ); - pthread_mutex_destroy( &proc->mutex_RU ); - pthread_mutex_destroy( &proc->mutex_RU_tx ); - } - - - void reset_opp_meas(void) { int sfn; reset_meas(&softmodem_stats_mt); @@ -998,7 +442,13 @@ 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[0][i]; +#if 0 +printf("before %p\n", gNB->common_vars.rxdataF[aa]); +#endif gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i]; +#if 0 +printf("after %p\n", gNB->common_vars.rxdataF[aa]); +#endif } } @@ -1007,15 +457,9 @@ void init_eNB_afterRU(void) { * (not tested in other modes). */ //init_precoding_weights(RC.gNB[inst]); - init_gNB_proc(inst); + init_gNB_Tpool(inst); } - for (ru_id=0; ru_idnr_wakeup_rxtx = wakeup_rxtx; - // RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_gNB; - RC.ru[ru_id]->gNB_top = gNB_top; - } } void init_gNB(int single_thread_flag,int wait_for_sync) { @@ -1024,18 +468,16 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { PHY_VARS_gNB *gNB; if (RC.gNB == NULL) { - RC.gNB = (PHY_VARS_gNB **) malloc((1+RC.nb_nr_L1_inst)*sizeof(PHY_VARS_gNB *)); - for (inst=0; instabstraction_flag = 0; gNB->single_thread_flag = single_thread_flag; @@ -1065,7 +507,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { } - LOG_I(PHY,"[nr-softmodem.c] gNB structure allocated\n"); + LOG_I(PHY,"[nr-gnb.c] gNB structure allocated\n"); } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 3a90edbf20..d0020d0c0e 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -114,6 +114,7 @@ int attach_rru(RU_t *ru); int connect_rau(RU_t *ru); uint16_t sf_ahead; +uint16_t slot_ahead; uint16_t sl_ahead; extern int emulate_rf; @@ -753,17 +754,25 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { if (fp->freq_range==nr_FR2) { // the beam index is written in bits 8-10 of the flags // bit 11 enables the gpio programming + // currently we switch beams every 10 slots (should = 1 TDD period in FR2) and we take the beam index of the first symbol of the first slot of this period int beam=0; - //if (slot==0) beam = 11; //3 for boresight & 8 to enable + if (slot%10==0) { + if (ru->common.beam_id[0][slot*fp->symbols_per_slot] < 8) { + beam = ru->common.beam_id[0][slot*fp->symbols_per_slot] | 8; + } + } /* - 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; + 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; - } + LOG_D(HW,"slot %d, beam %d\n",slot,ru->common.beam_id[0][slot*fp->symbols_per_slot]); + + } + 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 ); @@ -786,259 +795,6 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { } } - - -/*! - * \brief The Asynchronous RX/TX FH thread of RAU/RCC/gNB/RRU. - * This handles the RX FH for an asynchronous RRU/UE - * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -void *ru_thread_asynch_rxtx( void *param ) { - static int ru_thread_asynch_rxtx_status; - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = &ru->proc; - nfapi_nr_config_request_scf_t *cfg = &ru->config; - int slot=0, frame=0; - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe - wait_sync("ru_thread_asynch_rxtx"); - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe - printf( "waiting for devices (ru_thread_asynch_rx)\n"); - wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch"); - printf( "devices ok (ru_thread_asynch_rx)\n"); - - while (!oai_exit) { - - if (slot==ru->nr_frame_parms->slots_per_frame) { - slot=0; - frame++; - frame&=1023; - } else { - slot++; - } - - LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n"); - - // asynchronous receive from north (RRU IF4/IF5) - if (ru->fh_north_asynch_in) { - if ((nr_slot_select(cfg,frame,slot) & NR_DOWNLINK_SLOT)>0) - ru->fh_north_asynch_in(ru,&frame,&slot); - } else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n"); - } - - ru_thread_asynch_rxtx_status=0; - return(&ru_thread_asynch_rxtx_status); -} - - - - -/*! - * \brief The prach receive thread of RU. - * \param param is a \ref RU_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -void *ru_thread_prach( void *param ) { - static int ru_thread_prach_status; - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = (RU_proc_t *)&ru->proc; - // set default return value - ru_thread_prach_status = 0; - - while (RC.ru_mask>0) { - usleep(1e6); - LOG_I(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__); - } - - LOG_I(PHY,"%s() RU configured - RACH processing thread running\n", __FUNCTION__); - - while (!oai_exit) { - - - 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 ); - - if (ru->gNB_list[0]){ - prach_procedures( - ru->gNB_list[0],0 - ); - } - else { - rx_prach(NULL, - ru, - NULL, - NULL, - NULL, - proc->frame_prach, - 0,0 - ); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/ - if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; - } - - LOG_I(PHY, "Exiting RU thread PRACH\n"); - ru_thread_prach_status = 0; - return &ru_thread_prach_status; -} - - -int wakeup_synch(RU_t *ru) { - struct timespec wait; - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - // wake up synch thread - // lock the synch mutex and make sure the thread is ready - if (pthread_mutex_timedlock(&ru->proc.mutex_synch,&wait) != 0) { - LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU synch thread (IC %d)\n", ru->proc.instance_cnt_synch ); - exit_fun( "error locking mutex_synch" ); - return(-1); - } - - ++ru->proc.instance_cnt_synch; - - // the thread can now be woken up - if (pthread_cond_signal(&ru->proc.cond_synch) != 0) { - LOG_E( PHY, "[RU] ERROR pthread_cond_signal for RU synch thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } - - pthread_mutex_unlock( &ru->proc.mutex_synch ); - return(0); -} - -void do_ru_synch(RU_t *ru) { - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - RU_proc_t *proc = &ru->proc; - int i; - void *rxp[2],*rxp2[2]; - int32_t dummy_rx[ru->nb_rx][fp->samples_per_subframe] __attribute__((aligned(32))); - int rxs; - int ic; - - // initialize the synchronization buffer to the common_vars.rxdata - for (int i=0; inb_rx; i++) - rxp[i] = &ru->common.rxdata[i][0]; - - double temp_freq1 = ru->rfdevice.openair0_cfg->rx_freq[0]; - double temp_freq2 = ru->rfdevice.openair0_cfg->tx_freq[0]; - - for (i=0; i<4; i++) { - ru->rfdevice.openair0_cfg->rx_freq[i] = ru->rfdevice.openair0_cfg->tx_freq[i]; - ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq1; - } - - ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0); - - while ((ru->in_synch ==0)&&(!oai_exit)) { - // read in frame - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp, - fp->samples_per_subframe*10, - ru->nb_rx); - - if (rxs != fp->samples_per_subframe*10) LOG_E(PHY,"requested %d samples, got %d\n",fp->samples_per_subframe*10,rxs); - - // wakeup synchronization processing thread - wakeup_synch(ru); - ic=0; - - while ((ic>=0)&&(!oai_exit)) { - // continuously read in frames, 1ms at a time, - // until we are done with the synchronization procedure - for (i=0; inb_rx; i++) - rxp2[i] = (void *)&dummy_rx[i][0]; - - for (i=0; i<10; i++) - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp2, - fp->samples_per_subframe, - ru->nb_rx); - - pthread_mutex_lock(&ru->proc.mutex_synch); - ic = ru->proc.instance_cnt_synch; - pthread_mutex_unlock(&ru->proc.mutex_synch); - } // ic>=0 - } // in_synch==0 - - // read in rx_offset samples - LOG_I(PHY,"Resynchronizing by %d samples\n",ru->rx_offset); - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp, - ru->rx_offset, - ru->nb_rx); - - for (i=0; i<4; i++) { - ru->rfdevice.openair0_cfg->rx_freq[i] = temp_freq1; - ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq2; - } - - ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0); -} - - - -void wakeup_gNB_L1s(RU_t *ru) { - int i; - PHY_VARS_gNB **gNB_list = ru->gNB_list; - LOG_D(PHY,"wakeup_gNB_L1s (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top); - - if (ru->num_gNB==1 && ru->gNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) { - // call gNB function directly - char string[20]; - sprintf(string,"Incoming RU %u",ru->idx); - LOG_D(PHY,"RU %d Call gNB_top\n",ru->idx); - ru->gNB_top(gNB_list[0],ru->proc.frame_rx,ru->proc.tti_rx,string,ru); - } else { - LOG_D(PHY,"ru->num_gNB:%d\n", ru->num_gNB); - - for (i=0; inum_gNB; i++) { - LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->nr_wakeup_rxtx); - - if (ru->nr_wakeup_rxtx!=0 && ru->nr_wakeup_rxtx(gNB_list[i],ru) < 0) { - LOG_E(PHY,"could not wakeup gNB rxtx process for subframe %d\n", ru->proc.tti_rx); - } - } - } -} - -int wakeup_prach_ru(RU_t *ru) { - struct timespec wait; - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - if (pthread_mutex_timedlock(&ru->proc.mutex_prach,&wait) !=0) { - LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU prach thread (IC %d)\n", ru->proc.instance_cnt_prach); - exit_fun( "error locking mutex_rxtx" ); - return(-1); - } - - if (ru->proc.instance_cnt_prach==-1) { - ++ru->proc.instance_cnt_prach; - ru->proc.frame_prach = ru->proc.frame_rx; - ru->proc.subframe_prach = ru->proc.tti_rx; - - // DJP - think prach_procedures() is looking at gNB frame_prach - if (ru->gNB_list[0]) { - ru->gNB_list[0]->proc.frame_prach = ru->proc.frame_rx; - ru->gNB_list[0]->proc.slot_prach = ru->proc.tti_rx; - } - - LOG_I(PHY,"RU %d: waking up PRACH thread\n",ru->idx); - // the thread can now be woken up - AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n"); - } else LOG_W(PHY,"RU prach thread busy, skipping\n"); - - pthread_mutex_unlock( &ru->proc.mutex_prach ); - return(0); -} - // this is for RU with local RF unit void fill_rf_config(RU_t *ru, char *rf_config_file) { int i; @@ -1048,58 +804,21 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { int mu = config->ssb_config.scs_common.value; int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; - if (mu == NR_MU_0) { //or if LTE - if(N_RB == 100) { - 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 (mu == NR_MU_0) { + switch(N_RB) { + case 270: if (fp->threequarter_fs) { cfg->sample_rate=92.16e6; cfg->samples_per_frame = 921600; - cfg->tx_bw = 80e6; - cfg->rx_bw = 80e6; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; } else { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 80e6; - cfg->rx_bw = 80e6; + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; } - } else if(N_RB == 106) { + case 216: if (fp->threequarter_fs) { cfg->sample_rate=46.08e6; cfg->samples_per_frame = 460800; @@ -1112,20 +831,154 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->tx_bw = 40e6; cfg->rx_bw = 40e6; } - } else { + break; + case 106: + if (fp->threequarter_fs) { + cfg->sample_rate=23.04e6; + cfg->samples_per_frame = 230400; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + } + else { + cfg->sample_rate=30.72e6; + cfg->samples_per_frame = 307200; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + } + break; + case 52: + if (fp->threequarter_fs) { + cfg->sample_rate=11.52e6; + cfg->samples_per_frame = 115200; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + else { + cfg->sample_rate=15.36e6; + cfg->samples_per_frame = 153600; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + case 25: + if (fp->threequarter_fs) { + cfg->sample_rate=5.76e6; + cfg->samples_per_frame = 57600; + cfg->tx_bw = 5e6; + cfg->rx_bw = 5e6; + } + else { + cfg->sample_rate=7.68e6; + cfg->samples_per_frame = 76800; + cfg->tx_bw = 5e6; + cfg->rx_bw = 5e6; + } + break; + default: + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); + } + } else if (mu == NR_MU_1) { + switch(N_RB) { + case 273: + if (fp->threequarter_fs) { + cfg->sample_rate=184.32e6; + cfg->samples_per_frame = 1843200; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } else { + cfg->sample_rate=122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } + break; + case 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; + } + break; + case 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; + } + break; + case 51: + if (fp->threequarter_fs) { + cfg->sample_rate=23.04e6; + cfg->samples_per_frame = 230400; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + } + else { + cfg->sample_rate=30.72e6; + cfg->samples_per_frame = 307200; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + } + break; + case 24: + if (fp->threequarter_fs) { + cfg->sample_rate=11.52e6; + cfg->samples_per_frame = 115200; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + else { + cfg->sample_rate=15.36e6; + cfg->samples_per_frame = 153600; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + break; + default: 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; + switch(N_RB) { + case 66: + if (fp->threequarter_fs) { + cfg->sample_rate=184.32e6; + cfg->samples_per_frame = 1843200; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } else { + cfg->sample_rate = 122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } + break; + case 32: + if (fp->threequarter_fs) { + cfg->sample_rate=92.16e6; + cfg->samples_per_frame = 921600; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; + } else { + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; + } + break; + default: + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); } } else { AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); @@ -1172,60 +1025,52 @@ 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; + NR_DL_FRAME_PARMS *fp; 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); + fp = ru->nr_frame_parms; + printf("setup_RU_buffers: frame_parms = %p\n",fp); } 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; + case 0: //15 kHz scs + AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n"); + factor = fp->samples_per_subframe / 30720.0; + break; + case 1: //30 kHz sc + AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n"); + factor = fp->samples_per_subframe / 30720.0; + 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"); + factor = fp->samples_per_subframe / 61440.0; + break; + case 4: //240 kHz scs + AssertFatal(N_TA_offset == 431, "scs_common 240kHz only for FR2\n"); + factor = fp->samples_per_subframe / 61440.0; + break; + default: + AssertFatal(1==0, "Invalid scs_common!\n"); } - 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); + + LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d, mu %d)\n",ru->idx,ru->N_TA_offset,factor, + config->carrier_config.uplink_frequency.value, N_RB, mu); } else ru->N_TA_offset = 0; @@ -1297,136 +1142,61 @@ void *ru_stats_thread(void *param) { return(NULL); } -void *ru_thread_tx( void *param ) { - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = &ru->proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - PHY_VARS_gNB *gNB; - gNB_L1_proc_t *gNB_proc; - gNB_L1_rxtx_proc_t *L1_proc; - char filename[40]; - int print_frame = 8; - int i = 0; - int ret; - +void ru_tx_func(void *param) { - wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); - printf( "ru_thread_tx ready\n"); + processingData_RU_t *info = (processingData_RU_t *) param; + RU_t *ru = info->ru; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + int frame_tx = info->frame_tx; + int slot_tx = info->slot_tx; + int print_frame = 8; + char filename[40]; - while (!oai_exit) { + // do TX front-end processing if needed (precoding and/or IDFTs) + if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,slot_tx); - LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n"); - // wait until eNBs are finished subframe RX n and TX n+4 + // do OFDM with/without TX front-end processing if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,slot_tx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 1 ); - wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 0 ); + if(!emulate_rf) { + // do outgoing fronthaul (south) if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,slot_tx,info->timestamp_tx); - ret = pthread_mutex_lock(&proc->mutex_gNBs); - AssertFatal(ret == 0,"mutex_lock return %d\n",ret); - int frame_tx=proc->frame_tx; - int tti_tx =proc->tti_tx; - uint64_t timestamp_tx = proc->timestamp_tx; + if (ru->fh_north_out) ru->fh_north_out(ru); + } else { + if(frame_tx == print_frame) { + for (int i=0; inb_tx; i++) { - ret = pthread_mutex_unlock(&proc->mutex_gNBs); - AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); + if(slot_tx == 0) { + sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, slot_tx); + LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); - if (oai_exit) break; + sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, slot_tx); + LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx ); - - // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx); - - // do OFDM with/without TX front-end processing if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx); - - if(!emulate_rf) { - // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,tti_tx,timestamp_tx); - - if (ru->fh_north_out) ru->fh_north_out(ru); - } else { - if(proc->frame_tx == print_frame) { - for (i=0; inb_tx; i++) { - - if(proc->tti_tx == 0) { - sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); - - sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); - - sprintf(filename,"tx%ddataF_BF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_BF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); - } - - if(proc->tti_tx == 9) { - sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); - LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); - sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); - FILE *output_fd = fopen(filename,"w"); - - if (output_fd) { - fwrite(&ru->common.txdata[i][0], - sizeof(int32_t), - fp->samples_per_frame, - output_fd); - fclose(output_fd); - } else { - LOG_E(PHY,"Cannot write to file %s\n",filename); - } - }//if(proc->tti_tx == 9) - }//for (i=0; inb_tx; i++) - }//if(proc->frame_tx == print_frame) - }//else emulate_rf - - release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, proc->instance_cnt_gNBs); - - for(i = 0; inum_gNB; i++) { - gNB = ru->gNB_list[i]; - gNB_proc = &gNB->proc; - L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &gNB_proc->L1_proc_tx : &gNB_proc->L1_proc; - ret = pthread_mutex_lock(&gNB_proc->mutex_RU_tx); - AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); - - for (int j=0; jnum_RU; j++) { - if (ru == gNB->RU_list[j]) { - if ((gNB_proc->RU_mask_tx&(1< 0) - LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", - gNB->Mod_id,gNB_proc->frame_rx,gNB_proc->slot_rx,ru->idx,gNB->num_RU,gNB_proc->RU_mask_tx); - - gNB_proc->RU_mask_tx |= (1<common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); } - } - if (gNB_proc->RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return - ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); - AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); - } else { // all RUs TX are finished so send the ready signal to gNB processing - gNB_proc->RU_mask_tx = 0; - ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); - AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); + if(slot_tx == 9) { + sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); + LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); + sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); + FILE *output_fd = fopen(filename,"w"); - ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx); - AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); - // the thread can now be woken up - if (L1_proc->instance_cnt_RUs == -1) { - L1_proc->instance_cnt_RUs = 0; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); - AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, - "ERROR pthread_cond_signal for gNB_L1_thread\n"); - } //else AssertFatal(1==0,"gNB TX thread is not ready\n"); - ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx); - AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); - } - } - } - - release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); - return 0; + if (output_fd) { + fwrite(&ru->common.txdata[i][0], + sizeof(int32_t), + fp->samples_per_frame, + output_fd); + fclose(output_fd); + } else { + LOG_E(PHY,"Cannot write to file %s\n",filename); + } + }//if(slot_tx == 9) + }//for (i=0; inb_tx; i++) + }//if(frame_tx == print_frame) + }//else emulate_rf } void *ru_thread( void *param ) { @@ -1434,12 +1204,11 @@ void *ru_thread( void *param ) { RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + PHY_VARS_gNB *gNB = RC.gNB[0]; int ret; int slot = fp->slots_per_frame-1; int frame = 1023; - char filename[40], threadname[40]; - int print_frame = 8; - int i = 0; + char threadname[40]; int aa; nfapi_nr_config_request_scf_t *cfg = &ru->config; @@ -1499,6 +1268,15 @@ void *ru_thread( void *param ) { pthread_mutex_unlock(&RC.ru_mutex); wait_sync("ru_thread"); + notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1,rx_func); + notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1_tx,tx_func); + notifiedFIFO_elt_t *msgRUTx = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_RU_tx,ru_tx_func); + processingData_L1_t *syncMsg; + notifiedFIFO_elt_t *res; + pushNotifiedFIFO(gNB->resp_L1,msg); // to unblock the process in the beginning + pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning + pushNotifiedFIFO(gNB->resp_RU_tx,msgRUTx); // to unblock the process in the beginning + if(!emulate_rf) { // Start RF device if any if (ru->start_rf) { @@ -1507,19 +1285,6 @@ void *ru_thread( void *param ) { else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); } else LOG_I(PHY,"RU %d no rf device\n",ru->idx); - // if an asnych_rxtx thread exists - // wakeup the thread because the devices are ready at this point - - if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) { - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - proc->instance_cnt_asynch_rxtx=0; - pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - pthread_cond_signal(&proc->cond_asynch_rxtx); - } else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx); - - // if this is a slave RRU, try to synchronize on the DL frequency - if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); - // start trx write thread if(usrp_tx_thread == 1){ if (ru->start_write_thread){ @@ -1533,11 +1298,6 @@ void *ru_thread( void *param ) { } } - pthread_mutex_lock(&proc->mutex_FH1); - proc->instance_cnt_FH1 = 0; - pthread_mutex_unlock(&proc->mutex_FH1); - pthread_cond_signal(&proc->cond_FH1); - // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices while (!oai_exit) { // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. @@ -1555,31 +1315,23 @@ void *ru_thread( void *param ) { if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot); else AssertFatal(1==0, "No fronthaul interface at south port"); + proc->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe); + proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx; + proc->tti_tx = (proc->tti_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame; + LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n", frame,slot, proc->frame_rx,proc->tti_rx, proc->frame_tx,proc->tti_tx, RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx, RC.gNB[0]->proc.frame_tx); - /* - LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", - ru->do_prach, - is_prach_subframe(fp, proc->frame_rx, proc->tti_rx), - proc->frame_rx,proc->tti_rx); - if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->tti_rx)==1)) { - wakeup_prach_ru(ru); - }*/ - - // adjust for timing offset between RU - //printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->frame_rx, proc->tti_rx); if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; // do RX front-end processing (frequency-shift, dft) if needed int slot_type = nr_slot_select(cfg,proc->frame_rx,proc->tti_rx); if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { - //if (proc->tti_rx==8) { if (ru->feprx) { ru->feprx(ru,proc->tti_rx); @@ -1629,50 +1381,17 @@ void *ru_thread( void *param ) { } // At this point, all information for subframe has been received on FH interface + res = pullTpool(gNB->resp_L1, gNB->threadPool); + syncMsg = (processingData_L1_t *)NotifiedFifoData(res); + syncMsg->gNB = gNB; + syncMsg->frame_rx = proc->frame_rx; + syncMsg->slot_rx = proc->tti_rx; + syncMsg->frame_tx = proc->frame_tx; + syncMsg->slot_tx = proc->tti_tx; + syncMsg->timestamp_tx = proc->timestamp_tx; + res->key = proc->tti_rx; + pushTpool(gNB->threadPool, res); - // wakeup all gNB processes waiting for this RU - if (ru->num_gNB>0) wakeup_gNB_L1s(ru); - - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_gNB==0) { - // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); - - // do OFDM with/without TX front-end processing if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx); - - if(!emulate_rf) { - // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx); - - if (ru->fh_north_out) ru->fh_north_out(ru); - } else { - if(proc->frame_tx == print_frame) { - for (i=0; inb_tx; i++) { - sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_slot_wCP, 1, 1); - - if(proc->tti_tx == 9) { - sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); - LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1); - sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame); - FILE *output_fd = fopen(filename,"w"); - - if (output_fd) { - fwrite(&ru->common.txdata[i][0], - sizeof(int32_t), - fp->samples_per_frame, - output_fd); - fclose(output_fd); - } else { - LOG_E(PHY,"Cannot write to file %s\n",filename); - } - }//if(proc->tti_tx == 9) - }//for (i=0; inb_tx; i++) - }//if(proc->frame_tx == print_frame) - }//else emulate_rf - - proc->emulate_rf_busy = 0; - }//if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) } printf( "Exiting ru_thread \n"); @@ -1683,85 +1402,13 @@ void *ru_thread( void *param ) { else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); } + delNotifiedFIFO_elt(msg); + delNotifiedFIFO_elt(msgL1Tx); + delNotifiedFIFO_elt(msgRUTx); + ru_thread_status = 0; return &ru_thread_status; } -/* -// This thread run the initial synchronization like a UE -void *ru_thread_synch(void *arg) { - - RU_t *ru = (RU_t*)arg; - NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; - int32_t sync_pos,sync_pos2; - uint32_t peak_val; - uint32_t sync_corr[307200] __attribute__((aligned(32))); - static int ru_thread_synch_status; - - - - wait_sync("ru_thread_synch"); - - // initialize variables for PSS detection - lte_sync_time_init(ru->nr_frame_parms); - - while (!oai_exit) { - - // wait to be woken up - if (wait_on_condition(&ru->proc.mutex_synch,&ru->proc.cond_synch,&ru->proc.instance_cnt_synch,"ru_thread_synch")<0) break; - - // if we're not in synch, then run initial synch - if (ru->in_synch == 0) { - // run intial synch like UE - LOG_I(PHY,"Running initial synchronization\n"); - - sync_pos = lte_sync_time_gNB(ru->common.rxdata, - fp, - fp->samples_per_subframe*5, - &peak_val, - sync_corr); - LOG_I(PHY,"RU synch: %d, val %d\n",sync_pos,peak_val); - - if (sync_pos >= 0) { - if (sync_pos >= fp->nb_prefix_samples) - sync_pos2 = sync_pos - fp->nb_prefix_samples; - else - sync_pos2 = sync_pos + (fp->samples_per_subframe*10) - fp->nb_prefix_samples; - - if (fp->frame_type == FDD) { - - // PSS is hypothesized in last symbol of first slot in Frame - int sync_pos_slot = (fp->samples_per_subframe>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples; - - if (sync_pos2 >= sync_pos_slot) - ru->rx_offset = sync_pos2 - sync_pos_slot; - else - ru->rx_offset = (fp->samples_per_subframe*10) + sync_pos2 - sync_pos_slot; - } - else { - - } - - LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,ru->rx_offset); - - if ((peak_val > 300000) && (sync_pos > 0)) { - // if (sync_pos++ > 3) { - write_output("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_subframe*5,1,2); - write_output("ru_rx.m","rxs",(void*)ru->ru_time.rxdata[0][0],fp->samples_per_subframe*10,1,1); - exit(-1); - } - - ru->in_synch=1; - } - } - - if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break; - } // oai_exit - - ru_thread_synch_status = 0; - return &ru_thread_synch_status; - -} -*/ int nr_start_if(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB) { return(ru->ifdevice.trx_start_func(&ru->ifdevice)); @@ -1783,17 +1430,10 @@ int start_write_thread(RU_t *ru) { void init_RU_proc(RU_t *ru) { int i=0; RU_proc_t *proc; - char name[100]; LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); proc = &ru->proc; memset((void *)proc,0,sizeof(RU_proc_t)); proc->ru = ru; - proc->instance_cnt_prach = -1; - proc->instance_cnt_synch = -1; - proc->instance_cnt_FH = -1; - proc->instance_cnt_FH1 = -1; - proc->instance_cnt_gNBs = -1; - proc->instance_cnt_asynch_rxtx = -1; proc->instance_cnt_emulateRF = -1; proc->first_rx = 1; proc->first_tx = 1; @@ -1804,44 +1444,13 @@ void init_RU_proc(RU_t *ru) { for (i=0; i<10; i++) proc->symbol_mask[i]=0; - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); - pthread_mutex_init( &proc->mutex_synch,NULL); - pthread_mutex_init( &proc->mutex_FH,NULL); - pthread_mutex_init( &proc->mutex_FH1,NULL); pthread_mutex_init( &proc->mutex_emulateRF,NULL); - pthread_mutex_init( &proc->mutex_gNBs, NULL); - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_FH, NULL); - pthread_cond_init( &proc->cond_FH1, NULL); pthread_cond_init( &proc->cond_emulateRF, NULL); - pthread_cond_init( &proc->cond_asynch_rxtx, NULL); - pthread_cond_init( &proc->cond_synch,NULL); - pthread_cond_init( &proc->cond_gNBs, NULL); threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "thread_FH", -1, OAI_PRIORITY_RT_MAX ); - if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) - threadCreate( &proc->pthread_FH1, ru_thread_tx, (void *)ru, "thread_FH1", -1, OAI_PRIORITY_RT ); - if(emulate_rf) threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT ); - if (ru->function == NGFI_RRU_IF4p5) { - threadCreate( &proc->pthread_prach, ru_thread_prach, (void *)ru, "RACH", -1, OAI_PRIORITY_RT ); - ///tmp deactivation of synch thread - // if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void*)ru); - - if ((ru->if_timing == synch_to_other) || - (ru->function == NGFI_RRU_IF5) || - (ru->function == NGFI_RRU_IF4p5)) threadCreate( &proc->pthread_asynch_rxtx, ru_thread_asynch_rxtx, (void *)ru, "asynch_rxtx", -1, OAI_PRIORITY_RT ); - - snprintf( name, sizeof(name), "ru_thread_FH %d", ru->idx ); - pthread_setname_np( proc->pthread_FH, name ); - } else if (ru->function == gNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF - LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__); - threadCreate( &proc->pthread_prach, ru_thread_prach, (void *)ru,"RACH", -1, OAI_PRIORITY_RT ); - } - if (get_thread_worker_conf() == WORKER_ENABLE) { if (ru->feprx) nr_init_feprx_thread(ru); @@ -1854,46 +1463,9 @@ void init_RU_proc(RU_t *ru) { void kill_NR_RU_proc(int inst) { RU_t *ru = RC.ru[inst]; RU_proc_t *proc = &ru->proc; - pthread_mutex_lock(&proc->mutex_FH); - proc->instance_cnt_FH = 0; - pthread_mutex_unlock(&proc->mutex_FH); - pthread_cond_signal(&proc->cond_FH); - pthread_mutex_lock(&proc->mutex_prach); - proc->instance_cnt_prach = 0; - pthread_mutex_unlock(&proc->mutex_prach); - pthread_cond_signal(&proc->cond_prach); - pthread_mutex_lock(&proc->mutex_synch); - proc->instance_cnt_synch = 0; - pthread_mutex_unlock(&proc->mutex_synch); - pthread_cond_signal(&proc->cond_synch); - pthread_mutex_lock(&proc->mutex_gNBs); - proc->instance_cnt_gNBs = 0; - pthread_mutex_unlock(&proc->mutex_gNBs); - pthread_cond_signal(&proc->cond_gNBs); - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - proc->instance_cnt_asynch_rxtx = 0; - pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - pthread_cond_signal(&proc->cond_asynch_rxtx); LOG_D(PHY, "Joining pthread_FH\n"); pthread_join(proc->pthread_FH, NULL); - if (ru->function == NGFI_RRU_IF4p5) { - LOG_D(PHY, "Joining pthread_prach\n"); - pthread_join(proc->pthread_prach, NULL); - - if (ru->is_slave) { - LOG_D(PHY, "Joining pthread_\n"); - pthread_join(proc->pthread_synch, NULL); - } - - if ((ru->if_timing == synch_to_other) || - (ru->function == NGFI_RRU_IF5) || - (ru->function == NGFI_RRU_IF4p5)) { - LOG_D(PHY, "Joining pthread_asynch_rxtx\n"); - pthread_join(proc->pthread_asynch_rxtx, NULL); - } - } - if (get_nprocs() >= 2) { if (ru->feprx) { pthread_mutex_lock(&proc->mutex_fep); @@ -1922,17 +1494,6 @@ void kill_NR_RU_proc(int inst) { LOG_D(PHY, "Joining ru_stats_thread\n"); pthread_join(ru->ru_stats_thread, NULL); } - - pthread_mutex_destroy(&proc->mutex_prach); - pthread_mutex_destroy(&proc->mutex_asynch_rxtx); - pthread_mutex_destroy(&proc->mutex_synch); - pthread_mutex_destroy(&proc->mutex_FH); - pthread_mutex_destroy(&proc->mutex_gNBs); - pthread_cond_destroy(&proc->cond_prach); - pthread_cond_destroy(&proc->cond_FH); - pthread_cond_destroy(&proc->cond_asynch_rxtx); - pthread_cond_destroy(&proc->cond_synch); - pthread_cond_destroy(&proc->cond_gNBs); } int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) @@ -2167,11 +1728,9 @@ void set_function_spec_param(RU_t *ru) { ru->nr_start_if = NULL; // no if interface ru->rfdevice.host_type = RAU_HOST; - // FK this here looks messed up. The following lines should be part of the if (ru->function == gNodeB_3GPP), shouldn't they? - - ru->fh_south_in = rx_rf; // local synchronous RF RX - ru->fh_south_out = tx_rf; // local synchronous RF TX - ru->start_rf = start_rf; // need to start the local RF interface + ru->fh_south_in = rx_rf; // local synchronous RF RX + 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; ru->start_write_thread = start_write_thread; // starting RF TX in different thread printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf); diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 7884ca9e81..55b5928c16 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -86,12 +86,13 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "ngap_gNB.h" #include "gnb_paramdef.h" #include +#include "nfapi/oai_integration/vendor_ext.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 +extern uint8_t nfapi_mode; // Default to monolithic mode pthread_cond_t sync_cond; pthread_mutex_t sync_mutex; @@ -136,9 +137,6 @@ double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}}; double rx_gain_off = 0.0; -double sample_rate=30.72e6; -double bw = 10.0e6; - static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/; @@ -475,93 +473,6 @@ void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], } } -/* -void init_openair0(void) { - - int card; - int i; - - for (card=0; cardrf_config.dl_carrier_bandwidth.value == 100) { - if (frame_parms[0]->threequarter_fs) { - openair0_cfg[card].sample_rate=23.04e6; - openair0_cfg[card].samples_per_frame = 230400; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } else { - openair0_cfg[card].sample_rate=30.72e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } - } else if(config[0]->rf_config.dl_carrier_bandwidth.value == 50) { - openair0_cfg[card].sample_rate=15.36e6; - openair0_cfg[card].samples_per_frame = 153600; - openair0_cfg[card].tx_bw = 5e6; - openair0_cfg[card].rx_bw = 5e6; - } else if (config[0]->rf_config.dl_carrier_bandwidth.value == 25) { - openair0_cfg[card].sample_rate=7.68e6; - openair0_cfg[card].samples_per_frame = 76800; - openair0_cfg[card].tx_bw = 2.5e6; - openair0_cfg[card].rx_bw = 2.5e6; - } else if (config[0]->rf_config.dl_carrier_bandwidth.value == 6) { - openair0_cfg[card].sample_rate=1.92e6; - openair0_cfg[card].samples_per_frame = 19200; - openair0_cfg[card].tx_bw = 1.5e6; - openair0_cfg[card].rx_bw = 1.5e6; - } - - - if (config[0]->subframe_config.duplex_mode.value==TDD) - openair0_cfg[card].duplex_mode = duplex_mode_TDD; - else //FDD - openair0_cfg[card].duplex_mode = duplex_mode_FDD; - - printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, - RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value, - RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value ); - openair0_cfg[card].Mod_id = 0; - - openair0_cfg[card].num_rb_dl=config[0]->rf_config.dl_carrier_bandwidth.value; - - openair0_cfg[card].clock_source = clock_source; - - - openair0_cfg[card].tx_num_channels=min(2,RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value ); - openair0_cfg[card].rx_num_channels=min(2,RC.gNB[0]->gNB_config.rf_config.tx_antenna_ports.value ); - - for (i=0; i<4; i++) { - - if (irx_total_gain_dB; - - - 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]); - } - } // for loop on cards -} -*/ - 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 @@ -806,12 +717,11 @@ if(!IS_SOFTMODEM_NOS1) if(IS_SOFTMODEM_NOS1) init_pdcp(); + if (RC.nb_nr_L1_inst > 0) + RCconfig_NR_L1(); 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"); - RCconfig_L1(); } /* Start the agent. If it is turned off in the configuration, it won't start */ @@ -832,7 +742,7 @@ if(!IS_SOFTMODEM_NOS1) usleep(1000); - if (nfapi_mode) { + if (NFAPI_MODE) { printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); pthread_cond_init(&sync_cond,NULL); pthread_mutex_init(&sync_mutex, NULL); @@ -840,7 +750,7 @@ if(!IS_SOFTMODEM_NOS1) const char *nfapi_mode_str = ""; - switch(nfapi_mode) { + switch(NFAPI_MODE) { case 0: nfapi_mode_str = "MONOLITHIC"; break; @@ -860,7 +770,7 @@ if(!IS_SOFTMODEM_NOS1) printf("NFAPI MODE:%s\n", nfapi_mode_str); - if (nfapi_mode==2) // VNF + if (NFAPI_MODE==NFAPI_MODE_VNF) wait_nfapi_init("main?"); printf("START MAIN THREADS\n"); @@ -889,7 +799,7 @@ if(!IS_SOFTMODEM_NOS1) config_sync_var=0; - if (nfapi_mode==1) { // PNF + if (NFAPI_MODE==NFAPI_MODE_PNF) { wait_nfapi_init("main?"); } @@ -909,7 +819,7 @@ if(!IS_SOFTMODEM_NOS1) load_softscope("nr",&p); } - if (nfapi_mode != 1 && nfapi_mode != 2) { + if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) { printf("Not NFAPI mode - call init_eNB_afterRU()\n"); init_eNB_afterRU(); } else { diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 6be23582b1..47ddd7896e 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -85,12 +85,6 @@ * */ -#ifndef NO_RAT_NR - #define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */ -#else - #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 - typedef enum { pss = 0, pbch = 1, @@ -237,43 +231,6 @@ static void UE_synch(void *arg) { 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) { - case 6: - openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; - openair0_cfg[UE->rf_map.card].rx_bw =.96e6; - openair0_cfg[UE->rf_map.card].tx_bw =.96e6; - // openair0_cfg[0].rx_gain[0] -= 12; - break; - - case 25: - openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; - openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; - openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; - // openair0_cfg[0].rx_gain[0] -= 6; - break; - - case 50: - openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; - openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; - openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; - // openair0_cfg[0].rx_gain[0] -= 3; - break; - - case 100: - openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; - openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; - openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; - // openair0_cfg[0].rx_gain[0] -= 0; - break; - - case 66: - openair0_cfg[UE->rf_map.card].sample_rate=122.88e6; - openair0_cfg[UE->rf_map.card].rx_bw=100.e6; - openair0_cfg[UE->rf_map.card].tx_bw=100.e6; - break; - } - if (UE->mode != loop_through_memory) { UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); @@ -669,8 +626,8 @@ void *UE_thread(void *arg) { } curMsg->proc.timestamp_tx = timestamp+ - UE->frame_parms.get_samples_slot_timestamp(slot_nr, - &UE->frame_parms,DURATION_RX_TO_TX) - firstSymSamp; + UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX) + - firstSymSamp; notifiedFIFO_elt_t *res; @@ -692,8 +649,10 @@ void *UE_thread(void *arg) { decoded_frame_rx, curMsg->proc.frame_rx ); // 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; + 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) { @@ -703,25 +662,32 @@ void *UE_thread(void *arg) { 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) + + if (openair0_cfg[0].duplex_mode == duplex_mode_TDD) { + + uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots; + int nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + uint8_t num_UL_slots = nrofUplinkSlots + (nrofUplinkSlots != 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; + } else { 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),""); + 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); @@ -761,23 +727,6 @@ void init_NR_UE(int nb_inst, char* rrc_config_path) { AssertFatal((rrc_inst = nr_l3_init_ue(rrc_config_path)) != NULL, "can not initialize RRC module\n"); AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n"); AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n"); - - NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; - if (mac_inst->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) { - pusch_TimeDomainAllocationList = mac_inst->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup; - } - else if (mac_inst->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { - pusch_TimeDomainAllocationList = mac_inst->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } - - if (pusch_TimeDomainAllocationList) { - for(int i = 0; i < pusch_TimeDomainAllocationList->list.count; i++) { - AssertFatal(*pusch_TimeDomainAllocationList->list.array[i]->k2 >= DURATION_RX_TO_TX, - "Slot offset K2 (%ld) cannot be less than DURATION_RX_TO_TX (%d)\n", - *pusch_TimeDomainAllocationList->list.array[i]->k2, - DURATION_RX_TO_TX); - } - } } } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 864a33a58a..20e1e296e1 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -146,6 +146,7 @@ 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; @@ -315,92 +316,10 @@ void init_openair0(void) { for (card=0; cardthreequarter_fs; - numerology = frame_parms->numerology_index; - - if(frame_parms->N_RB_DL == 66) { - if (numerology==3) { - openair0_cfg[card].sample_rate=122.88e6; - openair0_cfg[card].samples_per_frame = 1228800; - } else { - LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n"); - exit(-1); - } - }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; - } else { - LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n"); - exit(-1); - } - }else if(frame_parms->N_RB_DL == 217) { - if (numerology==1) { - if (frame_parms->threequarter_fs) { - openair0_cfg[card].sample_rate=92.16e6; - openair0_cfg[card].samples_per_frame = 921600; - } - else { - openair0_cfg[card].sample_rate=122.88e6; - openair0_cfg[card].samples_per_frame = 1228800; - } - } else { - LOG_E(PHY,"Unsupported numerology!\n"); - exit(-1); - } - } else if(frame_parms->N_RB_DL == 273) { - if (numerology==1) { - if (frame_parms->threequarter_fs) { - AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); - } - else { - openair0_cfg[card].sample_rate=122.88e6; - openair0_cfg[card].samples_per_frame = 1228800; - } - } else { - LOG_E(PHY,"Unsupported numerology!\n"); - exit(-1); - } - } else if(frame_parms->N_RB_DL == 106) { - if (numerology==0) { - if (frame_parms->threequarter_fs) { - openair0_cfg[card].sample_rate=23.04e6; - openair0_cfg[card].samples_per_frame = 230400; - } else { - openair0_cfg[card].sample_rate=30.72e6; - openair0_cfg[card].samples_per_frame = 307200; - } - } else if (numerology==1) { - if (frame_parms->threequarter_fs) { - openair0_cfg[card].sample_rate=46.08e6; - openair0_cfg[card].samples_per_frame = 460800; - } - else { - openair0_cfg[card].sample_rate=61.44e6; - openair0_cfg[card].samples_per_frame = 614400; - } - } else if (numerology==2) { - openair0_cfg[card].sample_rate=122.88e6; - openair0_cfg[card].samples_per_frame = 1228800; - } else { - LOG_E(PHY,"Unsupported numerology!\n"); - exit(-1); - } - } 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->N_RB_DL == 25) { - openair0_cfg[card].sample_rate=7.68e6; - openair0_cfg[card].samples_per_frame = 76800; - } 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->N_RB_DL); - exit(-1); - } + openair0_cfg[card].configFilename = NULL; + openair0_cfg[card].threequarter_fs = frame_parms->threequarter_fs; + openair0_cfg[card].sample_rate = frame_parms->samples_per_subframe * 1e3; + openair0_cfg[card].samples_per_frame = frame_parms->samples_per_frame; if (frame_parms->frame_type==TDD) openair0_cfg[card].duplex_mode = duplex_mode_TDD; @@ -414,8 +333,9 @@ void init_openair0(void) { 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); - LOG_I(PHY, "HW: Configuring card %d, tx/rx num_channels %d/%d, duplex_mode %s\n", + LOG_I(PHY, "HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n", card, + openair0_cfg[card].sample_rate, openair0_cfg[card].tx_num_channels, openair0_cfg[card].rx_num_channels, duplex_mode[openair0_cfg[card].duplex_mode]); @@ -530,7 +450,8 @@ int main( int argc, char **argv ) { fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config; 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_symbol_rotation(&UE[CC_id]->frame_parms); init_nr_ue_vars(UE[CC_id], 0, abstraction_flag); #ifdef FR2_TEST @@ -556,11 +477,14 @@ int main( int argc, char **argv ) { init_NR_UE_threads(1); - config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); printf("UE threads created by %ld\n", gettid()); // wait for end of program printf("TYPE TO TERMINATE\n"); + // Sleep a while before checking all parameters have been used + // Some are used directly in external threads, asynchronously + sleep(20); + config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); while(true) sleep(3600); diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index b88fe29956..6d7d106e72 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -39,6 +39,8 @@ #include "executables/thread-common.h" #include "common/utils/LOG/log.h" #include "softmodem-common.h" +#include "nfapi/oai_integration/vendor_ext.h" + static softmodem_params_t softmodem_params; char *parallel_config=NULL; @@ -46,6 +48,7 @@ char *worker_config=NULL; msc_interface_t msc_interface; int usrp_tx_thread = 0; +uint8_t nfapi_mode=0; static mapping softmodem_funcs[] = MAPPING_SOFTMODEM_FUNCTIONS; static struct timespec start; @@ -145,6 +148,7 @@ void get_common_options(uint32_t execmask) { if(parallel_config != NULL) set_parallel_conf(parallel_config); if(worker_config != NULL) set_worker_conf(worker_config); + nfapi_setmode(nfapi_mode); } void softmodem_printresources(int sig, telnet_printfunc_t pf) { struct rusage usage; diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index cbace17717..3fd85888f5 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -92,6 +92,7 @@ extern "C" #define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n" +#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR\n" /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -113,6 +114,7 @@ extern "C" #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 NFAPI softmodem_params.nfapi #define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; @@ -145,6 +147,7 @@ extern int usrp_tx_thread; {"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}, \ {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ + {"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \ } @@ -232,6 +235,7 @@ typedef struct { int hw_timing_advance; uint32_t send_dmrs_sync; int use_256qam_table; + uint8_t nfapi; } softmodem_params_t; extern uint64_t get_softmodem_optmask(void); @@ -243,6 +247,14 @@ extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr); 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]; +extern uint16_t sl_ahead; +extern uint16_t sf_ahead; +extern volatile int oai_exit; + +void tx_func(void *param); +void rx_func(void *param); +void ru_tx_func(void *param); +extern uint8_t nfapi_mode; #ifdef __cplusplus } #endif diff --git a/nfapi/CHANGES.md b/nfapi/CHANGES.md new file mode 100644 index 0000000000..4dc68c6ff8 --- /dev/null +++ b/nfapi/CHANGES.md @@ -0,0 +1,2 @@ +# Changelog + diff --git a/nfapi/nrNFAPI.md b/nfapi/nrNFAPI.md new file mode 100644 index 0000000000..299a43fd93 --- /dev/null +++ b/nfapi/nrNFAPI.md @@ -0,0 +1,35 @@ +# Procedure to run nFAPI in 5G NR + +## Conributed by 5G Testbed IISC +### Developers: Sudhakar B,Mahesh K,Gokul S,Aniq U.R + +## Procedure to Build gNB and UE + +The regular commands to build gNB and UE can be used +``` +sudo ./build_oai --gNB --UE + +``` +## Procedure to run NR nFAPI using RF-Simulator + +### VNF command +``` +sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf --nfapi 2 --noS1 --phy-test + +``` +### PNF command +``` +sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf --nfapi 1 --rfsim --phy-test --rfsimulator.serveraddr server + +``` +### UE command +``` +sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . -d + +``` +## Procedure to run NR nFAPI using Hardware +Will be updated as we have not yet currently tested on hardware + +## Notes +* In order to acheive the synchronization between VNF and PNF and receive the P7 messages within the timing window the order in which we should run the modules on different terminals is UE->VNF->PNF +* Currently only downlink is functional and working as we are still working on uplink functionality diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 3dfbc2811d..4ca02ed929 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -30,6 +30,9 @@ #include "debug.h" #include "nfapi/oai_integration/vendor_ext.h" #include "nfapi_pnf_interface.h" +#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" + #include "nfapi.h" #include "nfapi_pnf.h" #include "common/ran_context.h" @@ -52,6 +55,11 @@ extern RAN_CONTEXT_t RC; #include "PHY/INIT/phy_init.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" +#include "openair1/SCHED_NR/fapi_nr_l1.h" +#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h" +#include "openair1/PHY/defs_gNB.h" + #define NUM_P5_PHY 2 @@ -75,17 +83,46 @@ extern void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1 extern void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); extern void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); extern void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu); +extern void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB, + int frame, int slot, + nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu); +extern void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB, + int frame, int slot, + nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu); +extern void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, + uint8_t *sdu); +extern void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu); +extern void nr_fill_ulsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pusch_pdu_t *ulsch_pdu); +extern void nr_fill_pucch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pucch_pdu_t *pucch_pdu); +extern void nr_fill_prach(PHY_VARS_gNB *gNB, + int SFN, + int Slot, + nfapi_nr_prach_pdu_t *prach_pdu); +extern void nr_fill_prach_ru(RU_t *ru, + int SFN, + int Slot, + nfapi_nr_prach_pdu_t *prach_pdu); + nfapi_tx_request_pdu_t *tx_request_pdu[1023][10][10]; // [frame][subframe][max_num_pdus] - +uint8_t nr_tx_pdus[32][16][4096]; +nfapi_nr_pdu_t *tx_data_request[1023][20][10]; //[frame][slot][max_num_pdus] uint8_t tx_pdus[32][8][4096]; nfapi_ue_release_request_body_t release_rntis; uint16_t phy_antenna_capability_values[] = { 1, 2, 4, 8, 16 }; -nfapi_pnf_param_response_t g_pnf_param_resp; +nfapi_nr_pnf_param_response_t g_pnf_param_resp; nfapi_pnf_p7_config_t *p7_config_g = NULL; @@ -248,6 +285,63 @@ void *pnf_p7_thread_start(void *ptr) { return 0; } +void *pnf_nr_p7_thread_start(void *ptr) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P7 THREAD %s\n", __FUNCTION__); + pnf_set_thread_priority(79); + nfapi_pnf_p7_config_t *config = (nfapi_pnf_p7_config_t *)ptr; + nfapi_nr_pnf_p7_start(config); + return 0; +} + +int pnf_nr_param_request(nfapi_pnf_config_t *config, nfapi_nr_pnf_param_request_t *req) { + printf("[PNF] pnf param request\n"); + nfapi_nr_pnf_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + pnf_info *pnf = (pnf_info *)(config->user_data); + resp.pnf_param_general.tl.tag = NFAPI_PNF_PARAM_GENERAL_TAG; + resp.pnf_param_general.nfapi_sync_mode = pnf->sync_mode; + resp.pnf_param_general.location_mode = pnf->location_mode; + resp.pnf_param_general.dl_config_timing = pnf->dl_config_timing; + resp.pnf_param_general.tx_timing = pnf->tx_timing; + resp.pnf_param_general.ul_config_timing = pnf->ul_config_timing; + resp.pnf_param_general.hi_dci0_timing = pnf->hi_dci0_timing; + resp.pnf_param_general.maximum_number_phys = pnf->max_phys; + resp.pnf_param_general.maximum_total_bandwidth = pnf->max_total_bw; + resp.pnf_param_general.maximum_total_number_dl_layers = pnf->max_total_dl_layers; + resp.pnf_param_general.maximum_total_number_ul_layers = pnf->max_total_ul_layers; + resp.pnf_param_general.shared_bands = pnf->shared_bands; + resp.pnf_param_general.shared_pa = pnf->shared_pa; + resp.pnf_param_general.maximum_total_power = pnf->max_total_power; + resp.pnf_phy.tl.tag = NFAPI_PNF_PHY_TAG; + resp.pnf_phy.number_of_phys = 1; + + for(int i = 0; i < 1; ++i) { + resp.pnf_phy.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy.phy[i].downlink_channel_bandwidth_supported = pnf->phys[i].dl_channel_bw_support; + resp.pnf_phy.phy[i].uplink_channel_bandwidth_supported = pnf->phys[i].ul_channel_bw_support; + resp.pnf_phy.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported; + resp.pnf_phy.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported; + resp.pnf_phy.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported; + resp.pnf_phy.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported; + resp.pnf_phy.phy[i].number_of_rfs = 2; + + for(int j = 0; j < 1; ++j) { + resp.pnf_phy.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j]; + } + + resp.pnf_phy.phy[i].number_of_rf_exclusions = 0; + + for(int j = 0; j < 0; ++j) { + resp.pnf_phy.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j]; + } + } + nfapi_nr_pnf_pnf_param_resp(config, &resp); + return 0; +} + + int pnf_param_request(nfapi_pnf_config_t *config, nfapi_pnf_param_request_t *req) { printf("[PNF] pnf param request\n"); nfapi_pnf_param_response_t resp; @@ -413,6 +507,21 @@ int pnf_config_request(nfapi_pnf_config_t *config, nfapi_pnf_config_request_t *r return 0; } +int pnf_nr_config_request(nfapi_pnf_config_t *config, nfapi_nr_pnf_config_request_t *req) { + printf("[PNF] pnf config request\n"); + pnf_info *pnf = (pnf_info *)(config->user_data); + phy_info *phy = pnf->phys; + phy->id = req->pnf_phy_rf_config.phy_rf_config[0].phy_id; + printf("[PNF] pnf config request assigned phy_id %d to phy_config_index %d\n", phy->id, req->pnf_phy_rf_config.phy_rf_config[0].phy_config_index); + nfapi_nr_pnf_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_nr_pnf_pnf_config_resp(config, &resp); + printf("[PNF] Sent pnf_config_resp\n"); + return 0; +} + void nfapi_send_pnf_start_resp(nfapi_pnf_config_t *config, uint16_t phy_id) { printf("Sending NFAPI_START_RESPONSE config:%p phy_id:%d\n", config, phy_id); nfapi_start_response_t start_resp; @@ -423,6 +532,16 @@ void nfapi_send_pnf_start_resp(nfapi_pnf_config_t *config, uint16_t phy_id) { nfapi_pnf_start_resp(config, &start_resp); } +void nfapi_nr_send_pnf_start_resp(nfapi_pnf_config_t *config, uint16_t phy_id) { + printf("Sending NFAPI_START_RESPONSE config:%p phy_id:%d\n", config, phy_id); + nfapi_nr_start_response_scf_t start_resp; + memset(&start_resp, 0, sizeof(start_resp)); + start_resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE; + start_resp.header.phy_id = phy_id; + start_resp.error_code = NFAPI_MSG_OK; + nfapi_nr_pnf_start_resp(config, &start_resp); +} + int pnf_start_request(nfapi_pnf_config_t *config, nfapi_pnf_start_request_t *req) { printf("Received NFAPI_PNF_START_REQUEST\n"); pnf_info *pnf = (pnf_info *)(config->user_data); @@ -441,6 +560,24 @@ int pnf_start_request(nfapi_pnf_config_t *config, nfapi_pnf_start_request_t *req return 0; } +int pnf_nr_start_request(nfapi_pnf_config_t *config, nfapi_nr_pnf_start_request_t *req) { + printf("Received NFAPI_PNF_START_REQUEST\n"); + pnf_info *pnf = (pnf_info *)(config->user_data); + // start all phys that have been configured + phy_info *phy = pnf->phys; + + if(phy->id != 0) { + nfapi_nr_pnf_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE; + resp.error_code = NFAPI_MSG_OK; + nfapi_nr_pnf_pnf_start_resp(config, &resp); + printf("[PNF] Sent NFAPI_PNF_START_RESP\n"); + } + + return 0; +} + int pnf_stop_request(nfapi_pnf_config_t *config, nfapi_pnf_stop_request_t *req) { printf("[PNF] Received NFAPI_PNF_STOP_REQ\n"); nfapi_pnf_stop_response_t resp; @@ -476,7 +613,228 @@ int param_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi return 0; } -int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_config_request_t *req) { +int nr_param_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_nr_param_request_scf_t *req) { + printf("[PNF] Received NFAPI_PARAM_REQUEST phy_id:%d\n", req->header.phy_id); + //pnf_info* pnf = (pnf_info*)(config->user_data); + nfapi_nr_param_response_scf_t nfapi_resp; + pnf_info *pnf = (pnf_info *)(config->user_data); + memset(&nfapi_resp, 0, sizeof(nfapi_resp)); + nfapi_resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE; + nfapi_resp.header.phy_id = req->header.phy_id; + nfapi_resp.error_code = 0; // DJP - what value??? + struct sockaddr_in pnf_p7_sockaddr; + + // ASSIGN TAGS + { + nfapi_resp.cell_param.release_capability.tl.tag = NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.cell_param.phy_state.tl.tag = NFAPI_NR_PARAM_TLV_PHY_STATE_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.cell_param.skip_blank_dl_config.tl.tag = NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.cell_param.skip_blank_ul_config.tl.tag = NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.cell_param.num_config_tlvs_to_report .tl.tag = NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.carrier_param.cyclic_prefix.tl.tag = NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.carrier_param.supported_subcarrier_spacings_dl.tl.tag = NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.carrier_param.supported_bandwidth_dl.tl.tag = NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.carrier_param.supported_subcarrier_spacings_ul.tl.tag = NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.carrier_param.supported_bandwidth_ul.tl.tag = NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdcch_param.cce_mapping_type.tl.tag = NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdcch_param.coreset_outside_first_3_of_ofdm_syms_of_slot.tl.tag = NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdcch_param.coreset_precoder_granularity_coreset.tl.tag = NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdcch_param.pdcch_mu_mimo.tl.tag = NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdcch_param.pdcch_precoder_cycling.tl.tag = NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdcch_param.max_pdcch_per_slot.tl.tag = NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pucch_param.pucch_formats.tl.tag = NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pucch_param.max_pucchs_per_slot.tl.tag = NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.pdsch_mapping_type.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.pdsch_dmrs_additional_pos.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.pdsch_allocation_types.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.pdsch_vrb_to_prb_mapping.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.pdsch_cbg.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.pdsch_dmrs_config_types.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.max_number_mimo_layers_pdsch.tl.tag = NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.max_mu_mimo_users_dl.tl.tag = NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.pdsch_data_in_dmrs_symbols.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.premption_support.tl.tag = NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pdsch_param.pdsch_non_slot_support.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.uci_mux_ulsch_in_pusch.tl.tag = NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.uci_only_pusch.tl.tag = NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.pusch_frequency_hopping.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.pusch_dmrs_config_types.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.pusch_dmrs_max_len.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.pusch_dmrs_additional_pos.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.pusch_cbg.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.pusch_mapping_type.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.pusch_allocation_types.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.pusch_vrb_to_prb_mapping.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.pusch_max_ptrs_ports.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.max_pduschs_tbs_per_slot.tl.tag = NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.max_number_mimo_layers_non_cb_pusch.tl.tag = NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.supported_modulation_order_ul.tl.tag = NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.max_mu_mimo_users_ul.tl.tag = NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.dfts_ofdm_support.tl.tag = NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.pusch_param.pusch_aggregation_factor.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.prach_param.prach_long_formats.tl.tag = NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.prach_param.prach_short_formats.tl.tag = NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.prach_param.prach_restricted_sets.tl.tag = NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.prach_param.max_prach_fd_occasions_in_a_slot.tl.tag = NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.measurement_param.rssi_measurement_support.tl.tag = NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.nfapi_config.p7_vnf_address_ipv6.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.nfapi_config.p7_pnf_address_ipv6.tl.tag = NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NR_NFAPI_P7_PNF_PORT_TAG; + nfapi_resp.num_tlv++; +/* + nfapi_resp.nfapi_config.dl_ue_per_sf.tl.tag = NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.nfapi_config.ul_ue_per_sf.tl.tag = NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.nfapi_config.rf_bands.tl.tag = NFAPI_NR_NFAPI_RF_BANDS_TAG; + nfapi_resp.num_tlv++; + nfapi_resp.nfapi_config.max_transmit_power.tl.tag = NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG; + nfapi_resp.num_tlv++; +*/ + nfapi_resp.nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG; + nfapi_resp.num_tlv++; + + nfapi_resp.nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG; + nfapi_resp.num_tlv++; + } + + nfapi_resp.nfapi_config.p7_pnf_port.value = 32123; //pnf->phys[0].local_port; DJP - hard code alert!!!! FIXME TODO + nfapi_resp.num_tlv++; + pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(pnf->phys[0].local_addr); + + memcpy(nfapi_resp.nfapi_config.p7_pnf_address_ipv4.address, &pnf_p7_sockaddr.sin_addr.s_addr, 4); + nfapi_resp.num_tlv++; + // P7 PNF Port + printf("TAG value :%d",nfapi_resp.cell_param.phy_state.tl.tag); + nfapi_nr_pnf_param_resp(config, &nfapi_resp); + + printf("[PNF] Sent NFAPI_PNF_PARAM_RESPONSE phy_id:%d number_of_tlvs:%u\n", req->header.phy_id, nfapi_resp.num_tlv); + printf("[PNF] param request .. exit\n"); + return 0; +} + +int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_config_request_t *req) +{ printf("[PNF] Received NFAPI_CONFIG_REQ phy_id:%d\n", req->header.phy_id); pnf_info *pnf = (pnf_info *)(config->user_data); uint8_t num_tlv = 0; @@ -657,8 +1015,7 @@ int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap phy_config_request(&phy_config); dump_frame_parms(fp); } - - phy_info->remote_port = req->nfapi_config.p7_vnf_port.value; + phy_info->remote_port = req->nfapi_config.p7_vnf_port.value; struct sockaddr_in vnf_p7_sockaddr; memcpy(&vnf_p7_sockaddr.sin_addr.s_addr, &(req->nfapi_config.p7_vnf_address_ipv4.address[0]), 4); phy_info->remote_addr = inet_ntoa(vnf_p7_sockaddr.sin_addr); @@ -678,6 +1035,100 @@ int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap return 0; } +int nr_config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_nr_config_request_scf_t *req) +{ + printf("[PNF] Received NFAPI_CONFIG_REQ phy_id:%d\n", req->header.phy_id); + pnf_info *pnf = (pnf_info *)(config->user_data); + uint8_t num_tlv = 0; + //struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + // In the case of nfapi_mode = 3 (UE = PNF) we should not have dependency on any eNB var. So we aim + // to keep only the necessary just to keep the nfapi FSM rolling by sending a dummy response. + NR_DL_FRAME_PARMS *fp; + + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; + fp = &gNB->frame_parms; + } else { + fp = (NR_DL_FRAME_PARMS *) malloc(sizeof(NR_DL_FRAME_PARMS)); + } + + phy_info *phy_info = pnf->phys; + + printf("\nTiming window tag: %d\n",NFAPI_NR_NFAPI_TIMING_WINDOW_TAG); + if(req->nfapi_config.timing_window.tl.tag == NFAPI_NR_NFAPI_TIMING_WINDOW_TAG) { + phy_info->timing_window = req->nfapi_config.timing_window.value; + printf("Phy_info:Timing window:%u NFAPI_CONFIG:timing_window:%u\n", phy_info->timing_window, req->nfapi_config.timing_window.value); + num_tlv++; + } + + if(req->nfapi_config.timing_info_mode.tl.tag == NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG) { + printf("timing info mode:%d\n", req->nfapi_config.timing_info_mode.value); + phy_info->timing_info_mode = req->nfapi_config.timing_info_mode.value; + num_tlv++; + } else { + phy_info->timing_info_mode = 0; + printf("NO timing info mode provided\n"); + } + //TODO: Read the P7 message offset values + if(req->nfapi_config.timing_info_period.tl.tag == NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG) { + printf("timing info period provided value:%d\n", req->nfapi_config.timing_info_period.value); + phy_info->timing_info_period = req->nfapi_config.timing_info_period.value; + num_tlv++; + } else { + phy_info->timing_info_period = 0; + } + + if(req->carrier_config.dl_bandwidth.tl.tag == NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG) { + phy_info->dl_channel_bw_support = req->carrier_config.dl_bandwidth.value; //rf_config.dl_channel_bandwidth.value; + fp->N_RB_DL = req->carrier_config.dl_bandwidth.value; //rf_config.dl_channel_bandwidth.value; + num_tlv++; + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG N_RB_DL:%u\n", __FUNCTION__, fp->N_RB_DL); + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() Missing NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG\n", __FUNCTION__); + } + + if(req->carrier_config.uplink_bandwidth.tl.tag == NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG) { + phy_info->ul_channel_bw_support = req->carrier_config.uplink_bandwidth.value; //req->rf_config.ul_channel_bandwidth.value; + fp->N_RB_UL = req->carrier_config.uplink_bandwidth.value; //req->rf_config.ul_channel_bandwidth.value; + num_tlv++; + } + + if (req->cell_config.phy_cell_id.tl.tag == NFAPI_NR_CONFIG_PHY_CELL_ID_TAG) { + fp->Nid_cell = req->cell_config.phy_cell_id.value; //sch_config.physical_cell_id.value; + fp->nushift = fp->Nid_cell%6; + num_tlv++; + } + + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + printf("[PNF] CONFIG_REQUEST[num_tlv:%d] TLVs processed:%d\n", req->num_tlv, num_tlv); + printf("[PNF] Simulating PHY CONFIG - DJP\n"); + NR_PHY_Config_t nr_phy_config; + nr_phy_config.Mod_id = 0; + nr_phy_config.CC_id=0; + nr_phy_config.cfg = req; + nr_phy_config_request(&nr_phy_config); + nr_dump_frame_parms(fp); + } + phy_info->remote_port = req->nfapi_config.p7_vnf_port.value; + struct sockaddr_in vnf_p7_sockaddr; + memcpy(&vnf_p7_sockaddr.sin_addr.s_addr, &(req->nfapi_config.p7_vnf_address_ipv4.address[0]), 4); + phy_info->remote_addr = inet_ntoa(vnf_p7_sockaddr.sin_addr); + printf("[PNF] %d vnf p7 %s:%d timing %d %d %d\n", phy_info->id, phy_info->remote_addr, phy_info->remote_port, + phy_info->timing_window, phy_info->timing_info_mode, phy_info->timing_info_period); + nfapi_nr_config_response_scf_t nfapi_resp; + memset(&nfapi_resp, 0, sizeof(nfapi_resp)); + nfapi_resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE; + nfapi_resp.header.phy_id = phy_info->id; + nfapi_resp.error_code = 0; // DJP - some value resp->error_code; + nfapi_nr_pnf_config_resp(config, &nfapi_resp); + printf("[PNF] Sent NFAPI_PNF_CONFIG_RESPONSE phy_id:%d\n", phy_info->id); + + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) + free(fp); + + return 0; +} + nfapi_p7_message_header_t *pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size) { if(message_id == P7_VENDOR_EXT_REQ) { (*msg_size) = sizeof(vendor_ext_p7_req); @@ -691,6 +1142,33 @@ void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) { free(header); } + +int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_dci_request_t *req) { + + // LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi); + + //phy_info* phy = (phy_info*)(pnf_p7->user_data); + struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; + if (proc ==NULL) + proc = &gNB->proc.L1_proc; + + for (int i=0; inumPdus; i++) { + //LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); + if (req->ul_dci_pdu_list[i].PDUType == 0) { + //LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_DCI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); + nfapi_nr_ul_dci_request_pdus_t *ul_dci_req_pdu = &req->ul_dci_pdu_list[i]; + int SFN=req->SFN+2; + handle_nfapi_nr_ul_dci_pdu(gNB, SFN, req->Slot, ul_dci_req_pdu); + } + else { + LOG_E(PHY,"[PNF] UL_DCI_REQ sfn_slot:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSLOT2DEC(req->SFN, req->Slot), i, req->ul_dci_pdu_list[i].PDUType); + } + } + + return 0; +} + + int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) { if (req->hi_dci0_request_body.number_of_dci == 0 && req->hi_dci0_request_body.number_of_hi == 0) LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi); @@ -719,6 +1197,97 @@ int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfa return 0; } + +int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_dl_tti_request_t *req) { + if (RC.ru == 0) { + return -1; + } + + if (RC.gNB == 0) { + return -2; + } + + if (RC.gNB[0] == 0) { + return -3; + } + + if (sync_var != 0) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy subframe?\n", __FUNCTION__); + return -4; + } + + int sfn = req->SFN; + int slot = req->Slot; + + struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; + if (proc==NULL) + proc = &gNB->proc.L1_proc; + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu_list = req->dl_tti_request_body.dl_tti_pdu_list; + + if (req->dl_tti_request_body.nPDUs) + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d; sfn:%d, slot:%d, nGroup:%u, nPDUs: %u, nUE: %u, PduIdx: %u,\n", + __FUNCTION__, proc->frame_tx, proc->slot_tx, proc->frame_rx, proc->slot_rx, // TODO: change subframes to slot + req->SFN, + req->Slot, + req->dl_tti_request_body.nGroup, + req->dl_tti_request_body.nPDUs, + req->dl_tti_request_body.nUe, + req->dl_tti_request_body.PduIdx); + + for (int i=0; idl_tti_request_body.nPDUs; i++) { + // TODO: enable after adding gNB PDCCH: + // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d pdcch_vars->num_dci:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size,pdcch_vars->num_dci); + + if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE) { + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu=&dl_tti_pdu_list[i]; + memcpy(dl_tti_pdu,&dl_tti_pdu_list[i],sizeof(nfapi_nr_dl_tti_request_pdu_t)); + int SFN=sfn+2; + handle_nfapi_nr_pdcch_pdu(gNB, SFN, slot, &dl_tti_pdu->pdcch_pdu); + //dl_tti_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15.numDlDci++; // ? + // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() pdcch_vars->num_dci:%d\n", __FUNCTION__, pdcch_vars->num_dci); + } else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PDU:%d BCH: pdu_index:%u pdu_length:%d sdu_length:%d BCH_SDU:%x,%x,%x\n", __FUNCTION__, i, pdu_index, bch_pdu->bch_pdu_rel8.length, tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_length, sdu[0], sdu[1], sdu[2]); + handle_nr_nfapi_ssb_pdu(gNB, sfn, slot, &dl_tti_pdu_list[i]); + gNB->pbch_configured=1; + //} else { + // NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() BCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pdu_index); + //} + } else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE) { + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu = &dl_tti_pdu_list[i].pdsch_pdu; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15_pdu = &pdsch_pdu->pdsch_pdu_rel15; + //nfapi_nr_tx_data_request_t *tx_data = tx_data_request[sfn][slot][rel15_pdu->pduIndex]; + nfapi_nr_pdu_t *tx_data = tx_data_request[sfn][slot][0]; + + if (tx_data != NULL) { + int UE_id = find_nr_dlsch(rel15_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE); + AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n"); + AssertFatal(UE_id= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX); + NR_gNB_DLSCH_t *dlsch0 = gNB->dlsch[UE_id][0]; + int harq_pid = dlsch0->harq_ids[sfn%2][slot]; + + if(harq_pid >= dlsch0->Mdlharq) { + LOG_E(PHY,"pnf_phy_dl_config_req illegal harq_pid %d\n", harq_pid); + return(-1); + } + //uint8_t *dlsch_sdu = (uint8_t *)tx_data->TLVs[0].value.direct; + uint8_t *dlsch_sdu = nr_tx_pdus[UE_id][harq_pid]; + memcpy(dlsch_sdu, tx_data->TLVs[0].value.direct,tx_data->PDU_length);//TODO: Check if required + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols); + handle_nr_nfapi_pdsch_pdu(gNB, sfn, slot,pdsch_pdu, dlsch_sdu); + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(sfn,slot), rel15_pdu->pduIndex); } + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_tti_pdu_list[i].PDUType); + } + } + + if(req->vendor_extension) + free(req->vendor_extension); + + return 0; +} + + 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.eNB == 0) { @@ -810,6 +1379,35 @@ int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, n return 0; } + + +int pnf_phy_tx_data_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_tx_data_request_t *req) { + uint16_t sfn = req->SFN; + uint16_t slot = req->Slot; + + if (req->Number_of_PDUs == 0) + LOG_D(PHY,"%s() SFN/SLOT:%d%d PDUs:%d\n", __FUNCTION__, sfn, slot, req->Number_of_PDUs); + + //if (req->pdu_list[0].TLVs->tag == NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST) { + for (int i=0; iNumber_of_PDUs; i++) { + // LOG_D(PHY,"%s() SFN/SF:%d%d number_of_pdus:%d [PDU:%d] pdu_length:%d pdu_index:%d num_segments:%d\n", + // __FUNCTION__, + // sfn, sf, + // req->tx_request_body.number_of_pdus, + // i, + // req->tx_request_body.tx_pdu_list[i].pdu_length, + // req->tx_request_body.tx_pdu_list[i].pdu_index, + // req->tx_request_body.tx_pdu_list[i].num_segments + // ); + // tx_request_pdu[sfn][sf][i] = &req->tx_request_body.tx_pdu_list[i]; + tx_data_request[sfn][slot][i] = &req->pdu_list[i]; + } + //} + + return 0; +} + + int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) { uint16_t sfn = NFAPI_SFNSF2SFN(req->sfn_sf); uint16_t sf = NFAPI_SFNSF2SF(req->sfn_sf); @@ -835,6 +1433,82 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) { return 0; } + + +int pnf_phy_ul_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_tti_request_t *req) { + // if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n", + // __FUNCTION__, + // NFAPI_SFNSF2DEC(req->sfn_sf), + // req->ul_config_request_body.number_of_pdus, + // req->ul_config_request_body.rach_prach_frequency_resources, + // req->ul_config_request_body.srs_present + // ); + + if (RC.ru == 0) { + return -1; + } + + if (RC.gNB == 0) { + return -2; + } + + if (RC.gNB[0] == 0) { + return -3; + } + + if (sync_var != 0) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy slot?\n", __FUNCTION__); + return -4; + } + uint16_t curr_sfn = req->SFN; + uint16_t curr_slot = req->Slot; + struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; + + if (proc==NULL) + proc = &gNB->proc.L1_proc; + + nfapi_nr_ul_tti_request_number_of_pdus_t *ul_tti_pdu_list = req->pdus_list; + + for (int i=0; i< req->n_pdus; i++) { + switch (ul_tti_pdu_list[i].pdu_type) { + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + //LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); + nr_fill_ulsch(gNB,curr_sfn, curr_slot, &ul_tti_pdu_list[i].pusch_pdu); + break; + case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: + //LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); + nr_fill_pucch(gNB,curr_sfn, curr_slot, &ul_tti_pdu_list[i].pucch_pdu); + break; + case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: + //LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); + nr_fill_prach(gNB, curr_sfn, curr_slot, &ul_tti_pdu_list[i].prach_pdu); + if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], curr_sfn, curr_slot, &ul_tti_pdu_list[i].prach_pdu); + break; + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_tti_pdu_list[i].pdu_type); + break; + + } + // //LOG_D(PHY, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, ul_config_pdu_list[i].pdu_size); + // if ( + // ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE || + // ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE || + // ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE || + // ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE + // ) { + // //LOG_D(PHY, "%s() handle_nfapi_ul_pdu() for PDU:%d\n", __FUNCTION__, i); + // // handle_nfapi_ul_pdu(eNB,proc,&ul_config_pdu_list[i],curr_sfn,curr_sf,req->ul_config_request_body.srs_present); + + // // TODO: dont have an NR function for this, also srs_present flag not there + + // } else { + // NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_tti_pdu_list[i].pdu_type); + // } + } + + return 0; +} + int pnf_phy_ul_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) { if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n", __FUNCTION__, @@ -983,6 +1657,7 @@ int pnf_sim_pack_vendor_extention_tlv(void *ve, uint8_t **ppWritePackedMsg, uint //printf("%s\n", __FUNCTION__); (void)ve; (void)ppWritePackedMsg; + return -1; } @@ -1000,7 +1675,7 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi p7_config->phy_id = phy->phy_id; p7_config->remote_p7_port = phy_info->remote_port; p7_config->remote_p7_addr = phy_info->remote_addr; - p7_config->local_p7_port = 32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port; + p7_config->local_p7_port = 32123;//phy_info->local_port;//50010; // DJP - good grief cannot seem to get the right answer phy_info->local_port; //DJP p7_config->local_p7_addr = (char*)phy_info->local_addr.c_str(); p7_config->local_p7_addr = phy_info->local_addr; printf("[PNF] P7 remote:%s:%d local:%s:%d\n", p7_config->remote_p7_addr, p7_config->remote_p7_port, p7_config->local_p7_addr, p7_config->local_p7_port); @@ -1111,6 +1786,142 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi return 0; } +int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_nr_start_request_scf_t *req) { + printf("[PNF] Received NFAPI_START_REQ phy_id:%d\n", req->header.phy_id); + nfapi_set_trace_level(NFAPI_TRACE_INFO); + pnf_info *pnf = (pnf_info *)(config->user_data); + phy_info *phy_info = pnf->phys; + nfapi_pnf_p7_config_t *p7_config = nfapi_pnf_p7_config_create(); + p7_config->phy_id = phy->phy_id; + p7_config->remote_p7_port = phy_info->remote_port; + p7_config->remote_p7_addr = phy_info->remote_addr; + // TODO: remove this hardcoded port + p7_config->local_p7_port = 32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port; + //DJP p7_config->local_p7_addr = (char*)phy_info->local_addr.c_str(); + p7_config->local_p7_addr = phy_info->local_addr; + printf("[PNF] P7 remote:%s:%d local:%s:%d\n", p7_config->remote_p7_addr, p7_config->remote_p7_port, p7_config->local_p7_addr, p7_config->local_p7_port); + p7_config->user_data = phy_info; + p7_config->malloc = &pnf_allocate; + p7_config->free = &pnf_deallocate; + p7_config->codec_config.allocate = &pnf_allocate; + p7_config->codec_config.deallocate = &pnf_deallocate; + p7_config->trace = &pnf_nfapi_trace; + phy->user_data = p7_config; + p7_config->subframe_buffer_size = phy_info->timing_window; + p7_config->slot_buffer_size = phy_info->timing_window; // TODO: check if correct for NR + printf("subframe_buffer_size configured using phy_info->timing_window:%d\n", phy_info->timing_window); + + if(phy_info->timing_info_mode & 0x1) { + p7_config->timing_info_mode_periodic = 1; + p7_config->timing_info_period = phy_info->timing_info_period; + } + + if(phy_info->timing_info_mode & 0x2) { + p7_config->timing_info_mode_aperiodic = 1; + } + + // NR + p7_config->dl_tti_req_fn = &pnf_phy_dl_tti_req; + p7_config->ul_tti_req_fn = &pnf_phy_ul_tti_req; + p7_config->ul_dci_req_fn = &pnf_phy_ul_dci_req; + p7_config->tx_data_req_fn = &pnf_phy_tx_data_req; + + // LTE + p7_config->dl_config_req = &pnf_phy_dl_config_req; + p7_config->ul_config_req = &pnf_phy_ul_config_req; + p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req; + p7_config->tx_req = &pnf_phy_tx_req; + p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; + p7_config->ue_release_req = &pnf_phy_ue_release_req; + if (NFAPI_MODE==NFAPI_UE_STUB_PNF) { + p7_config->dl_config_req = &memcpy_dl_config_req; + p7_config->ul_config_req = &memcpy_ul_config_req; + p7_config->hi_dci0_req = &memcpy_hi_dci0_req; + p7_config->tx_req = &memcpy_tx_req; + } else { + p7_config->dl_config_req = &pnf_phy_dl_config_req; + p7_config->ul_config_req = &pnf_phy_ul_config_req; + p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req; + p7_config->tx_req = &pnf_phy_tx_req; + } + + p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; + memset(&dummy_dl_config_req, 0, sizeof(dummy_dl_config_req)); + dummy_dl_config_req.dl_config_request_body.tl.tag=NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dummy_dl_config_req.dl_config_request_body.number_pdcch_ofdm_symbols=1; + dummy_dl_config_req.dl_config_request_body.number_dci=0; + dummy_dl_config_req.dl_config_request_body.number_pdu=0; + dummy_dl_config_req.dl_config_request_body.number_pdsch_rnti=0; + dummy_dl_config_req.dl_config_request_body.transmission_power_pcfich=6000; + dummy_dl_config_req.dl_config_request_body.dl_config_pdu_list=0; + memset(&dummy_tx_req, 0, sizeof(dummy_tx_req)); + dummy_tx_req.tx_request_body.number_of_pdus=0; + dummy_tx_req.tx_request_body.tl.tag=NFAPI_TX_REQUEST_BODY_TAG; + dummy_subframe.dl_config_req = &dummy_dl_config_req; + dummy_subframe.tx_req = 0;//&dummy_tx_req; + dummy_subframe.ul_config_req=0; + dummy_subframe.hi_dci0_req=0; + dummy_subframe.lbt_dl_config_req=0; + p7_config->dummy_subframe = dummy_subframe; + p7_config->vendor_ext = &pnf_phy_vendor_ext; + p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext; + p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext; + p7_config->codec_config.unpack_p7_vendor_extension = &pnf_phy_unpack_p7_vendor_extension; + p7_config->codec_config.pack_p7_vendor_extension = &pnf_phy_pack_p7_vendor_extension; + p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_phy_unpack_vendor_extension_tlv; + p7_config->codec_config.pack_vendor_extension_tlv = &pnf_phy_pack_vendor_extention_tlv; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating P7 thread %s\n", __FUNCTION__); + pthread_t p7_thread; + pthread_create(&p7_thread, NULL, &pnf_nr_p7_thread_start, p7_config); + //((pnf_phy_user_data_t*)(phy_info->fapi->user_data))->p7_config = p7_config; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Calling l1_north_init_eNB() %s\n", __FUNCTION__); + l1_north_init_gNB(); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] DJP - HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__); + p7_config_g = p7_config; + + // Need to wait for main thread to create RU structures + while(config_sync_var<0) { + usleep(5000000); + printf("[PNF] waiting for OAI to be configured (eNB/RU)\n"); + } + + printf("[PNF] OAI eNB/RU configured\n"); + //printf("[PNF] About to call phy_init_RU() for RC.ru[0]:%p\n", RC.ru[0]); + //phy_init_RU(RC.ru[0]); + printf("[PNF] About to call init_eNB_afterRU()\n"); + + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + init_eNB_afterRU(); + } + + // Signal to main thread that it can carry on - otherwise RU will startup too quickly and it is not initialised + { + pthread_mutex_lock(&nfapi_sync_mutex); + nfapi_sync_var=0; + pthread_cond_broadcast(&nfapi_sync_cond); + pthread_mutex_unlock(&nfapi_sync_mutex); + } + + while(sync_var<0) { + usleep(5000000); + printf("[PNF] waiting for OAI to be started\n"); + } + + printf("[PNF] Sending PNF_START_RESP\n"); + nfapi_nr_send_pnf_start_resp(config, p7_config->phy_id); + printf("[PNF] Sending first P7 slot indication\n"); +#if 1 + nfapi_pnf_p7_slot_ind(p7_config, p7_config->phy_id, 0, 0); + printf("[PNF] Sent first P7 slot ind\n"); +#else + nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct??? + printf("[PNF] Sent first P7 subframe ind\n"); +#endif + + + return 0; +} + int measurement_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_measurement_request_t *req) { nfapi_measurement_response_t resp; memset(&resp, 0, sizeof(resp)); @@ -1356,7 +2167,6 @@ int pnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, } /*------------------------------------------------------------------------------*/ - void *pnf_start_thread(void *ptr) { NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] IN PNF NFAPI start thread %s\n", __FUNCTION__); nfapi_pnf_config_t *config = (nfapi_pnf_config_t *)ptr; @@ -1367,18 +2177,76 @@ void *pnf_start_thread(void *ptr) { return (void *)0; } +void *pnf_nr_start_thread(void *ptr) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] IN PNF NFAPI start thread %s\n", __FUNCTION__); + nfapi_pnf_config_t *config = (nfapi_pnf_config_t *)ptr; + struct sched_param sp; + sp.sched_priority = 20; + pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp); + nfapi_nr_pnf_start(config); + return (void *)0; +} + +void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { + printf("%s() PNF\n\n\n\n\n\n", __FUNCTION__); + nfapi_setmode(NFAPI_MODE_PNF); // PNF! + + nfapi_pnf_config_t *config = nfapi_pnf_config_create(); + config->vnf_ip_addr = vnf_ip_addr; + config->vnf_p5_port = vnf_p5_port; + pnf.phys[0].udp.enabled = 1; + pnf.phys[0].udp.rx_port = 32123;//pnf_p7_port; + pnf.phys[0].udp.tx_port = vnf_p7_port; + strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr); + strcpy(pnf.phys[0].local_addr, pnf_ip_addr); + printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n", + __FUNCTION__,config->vnf_ip_addr, config->vnf_p5_port, + pnf.phys[0].local_addr, + pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port, + pnf.phys[0].udp.rx_port); + config->cell_search_req = &cell_search_request; + + + //config->pnf_nr_param_req = &pnf_nr_param_request; + config->pnf_nr_param_req = &pnf_nr_param_request; + config->pnf_nr_config_req = &pnf_nr_config_request; + config->pnf_nr_start_req = &pnf_nr_start_request; + config->pnf_stop_req = &pnf_stop_request; + config->nr_param_req = &nr_param_request; + config->nr_config_req = &nr_config_request; + config->nr_start_req = &nr_start_request; + config->measurement_req = &measurement_request; + config->rssi_req = &rssi_request; + config->broadcast_detect_req = &broadcast_detect_request; + config->system_information_schedule_req = &system_information_schedule_request; + config->system_information_req = &system_information_request; + config->nmm_stop_req = &nmm_stop_request; + config->vendor_ext = &vendor_ext; + config->trace = &pnf_nfapi_trace; + config->user_data = &pnf; + // To allow custom vendor extentions to be added to nfapi + config->codec_config.unpack_vendor_extension_tlv = &pnf_sim_unpack_vendor_extension_tlv; + config->codec_config.pack_vendor_extension_tlv = &pnf_sim_pack_vendor_extention_tlv; + config->allocate_p4_p5_vendor_ext = &pnf_sim_allocate_p4_p5_vendor_ext; + config->deallocate_p4_p5_vendor_ext = &pnf_sim_deallocate_p4_p5_vendor_ext; + config->codec_config.unpack_p4_p5_vendor_extension = &pnf_sim_unpack_p4_p5_vendor_extension; + config->codec_config.pack_p4_p5_vendor_extension = &pnf_sim_pack_p4_p5_vendor_extension; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating PNF NFAPI start thread %s\n", __FUNCTION__); + pthread_create(&pnf_start_pthread, NULL, &pnf_nr_start_thread, config); + pthread_setname_np(pnf_start_pthread, "NFAPI_PNF"); +} + void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { printf("%s() PNF\n\n\n\n\n\n", __FUNCTION__); if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) { nfapi_setmode(NFAPI_MODE_PNF); // PNF! } - nfapi_pnf_config_t *config = nfapi_pnf_config_create(); config->vnf_ip_addr = vnf_ip_addr; config->vnf_p5_port = vnf_p5_port; pnf.phys[0].udp.enabled = 1; - pnf.phys[0].udp.rx_port = pnf_p7_port; + pnf.phys[0].udp.rx_port = 32123;//pnf_p7_port; pnf.phys[0].udp.tx_port = vnf_p7_port; strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr); strcpy(pnf.phys[0].local_addr, pnf_ip_addr); @@ -1422,7 +2290,7 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf) { //TODO FIXME - HACK - DJP - using a global to bodge it in if (p7_config_g != NULL && sync_var==0) { - uint16_t sfn_sf_tx = sfn<<4 | sf; + uint16_t sfn_sf_tx = sfn<<4 | sf; if ((sfn % 100 == 0) && sf==0) { struct timespec ts; @@ -1441,6 +2309,52 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf) { } } + +long shift_ns,prev_ts_nsec,shift_us; +void oai_slot_ind(uint16_t sfn, uint16_t slot) { + + //slow down PNF + + LOG_D(PHY,"%s(sfn:%d, slot:%d)\n", __FUNCTION__, sfn, slot); + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + // if (!(sfn == 0 && slot == 0) && ts.tv_nsec > prev_ts_nsec){ + // shift_ns = ts.tv_nsec - prev_ts_nsec; + // shift_us = shift_ns/1000; + // printf("previous: %d, current: %d, shift: %d", prev_ts_nsec, ts.tv_nsec, shift_us); + // if(500-shift_us > 0) + // usleep(500-shift_us); + // // usleep(50); + // } + prev_ts_nsec = ts.tv_nsec; + + +//NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u slot:%u) SFN/SLOT(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, slot, NFAPI_SFNSLOT2DEC(sfn, slot)); + //TODO FIXME - HACK - DJP - using a global to bodge it in + if (p7_config_g != NULL && sync_var==0) { + // DONE: changed for NR x x x x x x x x x x x x x x - - - - - - : x (Frame), - (Slot) (max_numer =2) + uint16_t sfn_slot_tx = sfn<<6 | slot; + // if ((sfn % 100 == 0) && slot==0) { // DOUBT: Why 100? + // struct timespec ts; + // clock_gettime(CLOCK_MONOTONIC, &ts); + // NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u slot:%u) SFN/SLOT(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, slot, NFAPI_SFNSLOT2DEC(sfn, slot)); + // } + + //TODO: send p7_config instead of p7_config_g + int slot_ret = nfapi_pnf_p7_slot_ind(p7_config_g, p7_config_g->phy_id, sfn, slot); + + // if (subframe_ret) { + if (slot_ret) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s(frame:%u slot:%u) SFN/SLOT(TX):%u - PROBLEM with pnf_p7_slot_ind()\n", __FUNCTION__, sfn, slot, sfn_slot_tx, NFAPI_SFNSLOT2DEC(sfn, slot)); + // printing anything causes error: probably because there isn't enough time to accomodate a print statement + } else { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "***NFAPI subframe handler finished *** \n"); + } + } else { + } +} + int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) { rach_ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! LOG_D(PHY, "%s() sfn_sf:%d preambles:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(rach_ind->sfn_sf), rach_ind->rach_indication_body.number_of_preambles); diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h index 2c8201737c..b3ab7cbdbc 100644 --- a/nfapi/oai_integration/nfapi_pnf.h +++ b/nfapi/oai_integration/nfapi_pnf.h @@ -23,5 +23,8 @@ #define NFAPI_PNF_H__ int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); +void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); + void oai_subframe_ind(uint16_t sfn, uint16_t sf); +void oai_slot_ind(uint16_t sfn, uint16_t slot); #endif diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index f76cad87f7..485f17922f 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -39,8 +39,12 @@ #include "nfapi_vnf.h" #include "PHY/defs_eNB.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "common/ran_context.h" + +#define TEST + extern RAN_CONTEXT_t RC; extern UL_RCC_IND_t UL_RCC_INFO; @@ -189,11 +193,12 @@ int vnf_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t int vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p4_p5_codec_config_t *codec) { return -1; } - +void install_nr_schedule_handlers(NR_IF_Module_t *if_inst); void install_schedule_handlers(IF_Module_t *if_inst); extern int single_thread_flag; extern void init_eNB_afterRU(void); extern uint16_t sf_ahead; +extern uint16_t slot_ahead; void oai_create_enb(void) { int bodge_counter=0; @@ -231,6 +236,39 @@ void oai_enb_init(void) { init_eNB_afterRU(); } + +void oai_create_gnb(void) { + int bodge_counter=0; + PHY_VARS_gNB *gNB = RC.gNB[0]; + RC.nb_nr_CC = (int *)malloc(sizeof(int)); // TODO: find a better function to place this in + + gNB->Mod_id = bodge_counter; + gNB->CC_id = bodge_counter; + gNB->abstraction_flag = 0; + gNB->single_thread_flag = 0;//single_thread_flag; + RC.nb_nr_CC[bodge_counter] = 1; + + if (gNB->if_inst==0) { + gNB->if_inst = NR_IF_Module_init(bodge_counter); + } + + + // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY + // that will result in gNB->configured being set to TRUE. + // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values + if (RC.gNB[0]->if_inst==0 || RC.gNB[0]->if_inst->NR_PHY_config_req==0 || RC.gNB[0]->if_inst->NR_Schedule_response==0) { + printf("RC.gNB[0][0]->if_inst->NR_PHY_config_req is not installed - install it\n"); + install_nr_schedule_handlers(RC.gNB[0]->if_inst); + } + + do { + printf("%s() Waiting for gNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__); + usleep(50000); + } while(gNB->configured != 1); + + printf("%s() gNB is now configured\n", __FUNCTION__); +} + int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { printf("[VNF] pnf connection indication idx:%d\n", p5_idx); oai_create_enb(); @@ -241,6 +279,16 @@ int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { return 0; } +int pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { + printf("[VNF] pnf connection indication idx:%d\n", p5_idx); + oai_create_gnb(); + nfapi_nr_pnf_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST; + nfapi_nr_vnf_pnf_param_req(config, p5_idx, &req); + return 0; +} + int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { printf("[VNF] pnf disconnection indication idx:%d\n", p5_idx); vnf_info *vnf = (vnf_info *)(config->user_data); @@ -251,6 +299,42 @@ int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { return 0; } +int pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_param_response_t *resp) { + printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); + vnf_info *vnf = (vnf_info *)(config->user_data); + pnf_info *pnf = vnf->pnfs; + + for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) { + phy_info phy; + memset(&phy,0,sizeof(phy)); + phy.index = resp->pnf_phy.phy[i].phy_config_index; + printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); + nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id)); + + for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) { + printf("[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); + phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index; + } + + pnf->phys[0] = phy; + } + nfapi_nr_pnf_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; + req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; + req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size(); + printf("DJP:Hard coded num phy rf to 2\n"); + + for(unsigned i = 0; i < 2; ++i) { + req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id; + req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index; + req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0]; + } + + nfapi_nr_vnf_pnf_config_req(config, p5_idx, &req); + return 0; +} + int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_response_t *resp) { printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); vnf_info *vnf = (vnf_info *)(config->user_data); @@ -270,7 +354,6 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re pnf->phys[0] = phy; } - for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i) { rf_info rf; memset(&rf,0,sizeof(rf)); @@ -278,7 +361,6 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re printf("[VNF] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index); pnf->rfs[0] = rf; } - nfapi_pnf_config_request_t req; memset(&req, 0, sizeof(req)); req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; @@ -296,6 +378,31 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re return 0; } +int pnf_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_config_response_t *resp) { + printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length); + + if(1) { + nfapi_nr_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.phy_id = resp->header.phy_id; + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req); + } else { + // Rather than send the pnf_start_request we will demonstrate + // sending a vendor extention message. The start request will be + // send when the vendor extension response is received + //vnf_info* vnf = (vnf_info*)(config->user_data); + vendor_ext_p5_req req; + memset(&req, 0, sizeof(req)); + req.header.message_id = P5_VENDOR_EXT_REQ; + req.dummy1 = 45; + req.dummy2 = 1977; + nfapi_vnf_vendor_extension(config, p5_idx, &req.header); + } + + return 0; +} + int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_response_t *resp) { printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length); @@ -321,6 +428,70 @@ int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_ return 0; } +int wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) { + struct timespec curr_t; + clock_gettime(CLOCK_MONOTONIC,&curr_t); + //printf("\n wake_gNB_rxtx before assignment sfn:%d slot:%d TIME %d.%d",sfn,slot,curr_t.tv_sec,curr_t.tv_nsec); + gNB_L1_proc_t *proc=&gNB->proc; + gNB_L1_rxtx_proc_t *L1_proc= (slot&1)? &proc->L1_proc : &proc->L1_proc_tx; + + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + //printf("%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf); + //int i; + struct timespec wait; + clock_gettime(CLOCK_REALTIME, &wait); + wait.tv_sec = 0; + wait.tv_nsec +=5000L; + //wait.tv_nsec = 0; + // 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, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt ); + exit_fun( "error locking mutex_rxtx" ); + return(-1); + } + + { + static uint16_t old_slot = 0; + static uint16_t old_sfn = 0; + proc->slot_rx = old_slot; + proc->frame_rx = old_sfn; + // Try to be 1 frame back + old_slot = slot; + old_sfn = sfn; + //printf("\n wake_gNB_rxtx after assignment sfn:%d slot:%d",proc->frame_rx,proc->slot_rx); + if (old_slot == 0 && old_sfn % 100 == 0) LOG_W( PHY,"[gNB] sfn/slot:%d%d old_sfn/slot:%d%d proc[rx:%d%d]\n", sfn, slot, old_sfn, old_slot, proc->frame_rx, proc->slot_rx); + } + + ++L1_proc->instance_cnt; + //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 + // transmitted timestamp of the next TX slot (first). + // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, + // we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti, + // and proc->subframe_tx = proc->subframe_rx+sf_ahead + L1_proc->timestamp_tx = proc->timestamp_rx + (slot_ahead *fp->samples_per_subframe); + L1_proc->frame_rx = proc->frame_rx; + L1_proc->slot_rx = proc->slot_rx; + L1_proc->frame_tx = (L1_proc->slot_rx > (19-slot_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; + L1_proc->slot_tx = (L1_proc->slot_rx + slot_ahead)%20; + + //LOG_I(PHY, "sfn/sf:%d%d proc[rx:%d%d] rx:%d%d] About to wake rxtx thread\n\n", sfn, slot, proc->frame_rx, proc->slot_rx, L1_proc->frame_rx, L1_proc->slot_rx); + //printf("\nEntering wake_gNB_rxtx sfn %d slot %d\n",L1_proc->frame_rx,L1_proc->slot_rx); + // the thread can now be woken up + if (pthread_cond_signal(&L1_proc->cond) != 0) { + LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n"); + exit_fun( "ERROR pthread_clond_signal" ); + 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); +} + int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { L1_proc_t *proc=&eNB->proc; L1_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx; @@ -416,6 +587,7 @@ int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) { printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST"); if (sync==1 && nfapi_sync_var!=0) { + printf("[VNF] Signal to OAI main code that it can go\n"); pthread_mutex_lock(&nfapi_sync_mutex); nfapi_sync_var=0; @@ -426,6 +598,29 @@ int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) { return(0); } + +int phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot) { + static uint8_t first_time = 1; + + if (first_time) { + printf("[VNF] slot indication %d\n", NFAPI_SFNSLOT2DEC(sfn, slot)); + first_time = 0; + } + + if (RC.gNB && RC.gNB[0]->configured) { + // uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf); + // uint16_t sf = NFAPI_SFNSF2SF(sfn_sf); + LOG_D(PHY,"[VNF] slot indication sfn:%d sf:%d\n", sfn, slot); + wake_gNB_rxtx(RC.gNB[0], sfn, slot); // DONE: find NR equivalent + } else { + printf("[VNF] %s() RC.gNB:%p\n", __FUNCTION__, RC.gNB); + + if (RC.gNB) printf("RC.gNB[0]->configured:%d\n", RC.gNB[0]->configured); + } + + return 0; +} + int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn_sf) { static uint8_t first_time = 1; @@ -937,6 +1132,14 @@ int vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_ static pthread_t vnf_start_pthread; static pthread_t vnf_p7_start_pthread; +void *vnf_nr_p7_start_thread(void *ptr) { + printf("%s()\n", __FUNCTION__); + pthread_setname_np(pthread_self(), "VNF_P7"); + nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr; + nfapi_nr_vnf_p7_start(config); + return config; +} + void *vnf_p7_start_thread(void *ptr) { printf("%s()\n", __FUNCTION__); pthread_setname_np(pthread_self(), "VNF_P7"); @@ -947,12 +1150,13 @@ void *vnf_p7_start_thread(void *ptr) { void set_thread_priority(int priority); -void *vnf_p7_thread_start(void *ptr) { +void *vnf_nr_p7_thread_start(void *ptr) { set_thread_priority(79); vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr; p7_vnf->config->port = p7_vnf->local_port; p7_vnf->config->sync_indication = &phy_sync_indication; - p7_vnf->config->subframe_indication = &phy_subframe_indication; + p7_vnf->config->slot_indication = &phy_slot_indication; + p7_vnf->config->harq_indication = &phy_harq_indication; p7_vnf->config->crc_indication = &phy_crc_indication; p7_vnf->config->rx_indication = &phy_rx_indication; @@ -977,11 +1181,72 @@ void *vnf_p7_thread_start(void *ptr) { p7_vnf->config->codec_config.deallocate = &vnf_deallocate; p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext; p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext; - NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__); + pthread_create(&vnf_p7_start_pthread, NULL, &vnf_nr_p7_start_thread, p7_vnf->config); + return 0; +} + +void *vnf_p7_thread_start(void *ptr) { + set_thread_priority(79); + vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr; + p7_vnf->config->port = p7_vnf->local_port; + p7_vnf->config->sync_indication = &phy_sync_indication; + p7_vnf->config->subframe_indication = &phy_subframe_indication; + p7_vnf->config->slot_indication = &phy_slot_indication; + + p7_vnf->config->harq_indication = &phy_harq_indication; + p7_vnf->config->crc_indication = &phy_crc_indication; + p7_vnf->config->rx_indication = &phy_rx_indication; + p7_vnf->config->rach_indication = &phy_rach_indication; + p7_vnf->config->srs_indication = &phy_srs_indication; + p7_vnf->config->sr_indication = &phy_sr_indication; + p7_vnf->config->cqi_indication = &phy_cqi_indication; + p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication; + p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication; + p7_vnf->config->nrach_indication = &phy_nrach_indication; + p7_vnf->config->malloc = &vnf_allocate; + p7_vnf->config->free = &vnf_deallocate; + p7_vnf->config->trace = &vnf_trace; + p7_vnf->config->vendor_ext = &phy_vendor_ext; + p7_vnf->config->user_data = p7_vnf; + p7_vnf->mac->user_data = p7_vnf; + p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension; + p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension; + p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv; + p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv; + p7_vnf->config->codec_config.allocate = &vnf_allocate; + p7_vnf->config->codec_config.deallocate = &vnf_deallocate; + p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext; + p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__); pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config); return 0; } +int pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_start_response_t *resp) { + vnf_info *vnf = (vnf_info *)(config->user_data); + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + pnf_info *pnf = vnf->pnfs; + nfapi_nr_param_request_scf_t req; + printf("[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started); + + if(p7_vnf->thread_started == 0) { + pthread_t vnf_p7_thread; + pthread_create(&vnf_p7_thread, NULL, &vnf_nr_p7_thread_start, p7_vnf); + p7_vnf->thread_started = 1; + } else { + // P7 thread already running. + } + + // start all the phys in the pnf. + printf("[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST; + req.header.phy_id = pnf->phys[0].id; + nfapi_nr_vnf_param_req(config, p5_idx, &req); + return 0; +} + int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_response_t *resp) { vnf_info *vnf = (vnf_info *)(config->user_data); vnf_p7_info *p7_vnf = vnf->p7_vnfs; @@ -998,7 +1263,7 @@ int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_re } // start all the phys in the pnf. - printf("[VNF] Sending NFAPI_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); + printf("[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); memset(&req, 0, sizeof(req)); req.header.message_id = NFAPI_PARAM_REQUEST; req.header.phy_id = pnf->phys[0].id; @@ -1008,6 +1273,69 @@ int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_re extern uint32_t to_earfcn(int eutra_bandP,uint32_t dl_CarrierFreq,uint32_t bw); +int nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_response_scf_t *resp) { + + printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + vnf_info *vnf = (vnf_info *)(config->user_data); + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + struct sockaddr_in pnf_p7_sockaddr; + nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; // check + phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value; + memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4); + phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr); + // for now just 1 + printf("[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, + p7_vnf->periodic_timing_period); + req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST; + req->header.phy_id = phy->id; + printf("[VNF] Send NFAPI_CONFIG_REQUEST\n"); + //printf("\n NR bandP =%d\n",req->nfapi_config.rf_bands.rf_band[0]); + + req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG; + req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port; + req->num_tlv++; + printf("[VNF] DJP local_port:%d\n", p7_vnf->local_port); + req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + struct sockaddr_in vnf_p7_sockaddr; + vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr); + memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4); + req->num_tlv++; + printf("[VNF] DJP local_addr:%s\n", p7_vnf->local_addr); + req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG; + req->nfapi_config.timing_window.value = p7_vnf->timing_window; + printf("\n[VNF]Timing window tag : %d Timing window:%u\n",NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, p7_vnf->timing_window); + req->num_tlv++; + + if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) { + req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG; + req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled); + req->num_tlv++; + + if(p7_vnf->periodic_timing_enabled) { + req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG; + req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period; + req->num_tlv++; + } + } +//TODO: Assign tag and value for P7 message offsets +req->nfapi_config.dl_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET; +req->nfapi_config.ul_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET; +req->nfapi_config.ul_dci_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET; +req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET; + + vendor_ext_tlv_2 ve2; + memset(&ve2, 0, sizeof(ve2)); + ve2.tl.tag = VENDOR_EXT_TLV_2_TAG; + ve2.dummy = 2016; + req->vendor_extension = &ve2.tl; + nfapi_nr_vnf_config_req(config, p5_idx, req); + printf("[VNF] Sent NFAPI_VNF_CONFIG_REQ num_tlv:%u\n",req->num_tlv); + return 0; +} + + int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t *resp) { printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); vnf_info *vnf = (vnf_info *)(config->user_data); @@ -1016,7 +1344,7 @@ int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t phy_info *phy = pnf->phys; struct sockaddr_in pnf_p7_sockaddr; nfapi_config_request_t *req = &RC.mac[0]->config[0]; - phy->remote_port = resp->nfapi_config.p7_pnf_port.value; + phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value; memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4); phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr); // for now just 1 @@ -1062,6 +1390,19 @@ int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t return 0; } +int nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_config_response_scf_t *resp) { + nfapi_nr_start_request_scf_t req; + printf("[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + printf("[VNF] Calling oai_enb_init()\n"); + oai_enb_init(); // TODO: change to gnb + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_REQUEST; + req.header.phy_id = resp->header.phy_id; + nfapi_nr_vnf_start_req(config, p5_idx, &req); + printf("[VNF] Send NFAPI_VNF_START_REQUEST idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + return 0; +} + int config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_config_response_t *resp) { nfapi_start_request_t req; printf("[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); @@ -1085,6 +1426,17 @@ int start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_start_response_t return 0; } +int nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_response_scf_t *resp) { + printf("[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + vnf_info *vnf = (vnf_info *)(config->user_data); + pnf_info *pnf = vnf->pnfs; + phy_info *phy = pnf->phys; + vnf_p7_info *p7_vnf = vnf->p7_vnfs; + + nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id); + return 0; +} + int vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg) { printf("[VNF] %s\n", __FUNCTION__); @@ -1129,6 +1481,13 @@ void vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header) { nfapi_vnf_config_t *config = 0; +void vnf_nr_start_thread(void *ptr) { + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] VNF NFAPI thread - nfapi_vnf_start()%s\n", __FUNCTION__); + pthread_setname_np(pthread_self(), "VNF"); + config = (nfapi_vnf_config_t *)ptr; + nfapi_nr_vnf_start(config); +} + void vnf_start_thread(void *ptr) { NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] VNF NFAPI thread - nfapi_vnf_start()%s\n", __FUNCTION__); pthread_setname_np(pthread_self(), "VNF"); @@ -1138,7 +1497,57 @@ void vnf_start_thread(void *ptr) { static vnf_info vnf; -/*------------------------------------------------------------------------------*/ +void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { + nfapi_setmode(NFAPI_MODE_VNF); + memset(&vnf, 0, sizeof(vnf)); + memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs)); + vnf.p7_vnfs[0].timing_window = 32; + vnf.p7_vnfs[0].periodic_timing_enabled = 1; + vnf.p7_vnfs[0].aperiodic_timing_enabled = 0; + vnf.p7_vnfs[0].periodic_timing_period = 10; + vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create(); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port); + strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr); + //vnf.p7_vnfs[0].local_port = vnf.p7_vnfs[0].local_port; // 50001; // TODO: remove hardcode + vnf.p7_vnfs[0].local_port = 50011; + vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t)); + nfapi_vnf_config_t *config = nfapi_vnf_config_create(); + config->malloc = malloc; + config->free = free; + config->trace = &vnf_trace; + config->vnf_p5_port = vnf_p5_port; + config->vnf_ipv4 = 1; + config->vnf_ipv6 = 0; + config->pnf_list = 0; + config->phy_list = 0; + + config->pnf_nr_connection_indication = &pnf_nr_connection_indication_cb; + config->pnf_disconnect_indication = &pnf_disconnection_indication_cb; + + config->pnf_nr_param_resp = &pnf_nr_param_resp_cb; + config->pnf_nr_config_resp = &pnf_nr_config_resp_cb; + config->pnf_nr_start_resp = &pnf_nr_start_resp_cb; + config->nr_param_resp = &nr_param_resp_cb; + config->nr_config_resp = &nr_config_resp_cb; + config->nr_start_resp = &nr_start_resp_cb; + config->vendor_ext = &vendor_ext_cb; + config->user_data = &vnf; + // To allow custom vendor extentions to be added to nfapi + config->codec_config.unpack_vendor_extension_tlv = &vnf_unpack_vendor_extension_tlv; + config->codec_config.pack_vendor_extension_tlv = &vnf_pack_vendor_extension_tlv; + config->codec_config.unpack_p4_p5_vendor_extension = &vnf_unpack_p4_p5_vendor_extension; + config->codec_config.pack_p4_p5_vendor_extension = &vnf_pack_p4_p5_vendor_extension; + config->allocate_p4_p5_vendor_ext = &vnf_allocate_p4_p5_vendor_ext; + config->deallocate_p4_p5_vendor_ext = &vnf_deallocate_p4_p5_vendor_ext; + config->codec_config.allocate = &vnf_allocate; + config->codec_config.deallocate = &vnf_deallocate; + memset(&UL_RCC_INFO,0,sizeof(UL_RCC_IND_t)); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); + pthread_create(&vnf_start_pthread, NULL, (void *)&vnf_nr_start_thread, config); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__); +} + + void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { nfapi_setmode(NFAPI_MODE_VNF); memset(&vnf, 0, sizeof(vnf)); @@ -1150,7 +1559,8 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create(); NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port); strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr); - vnf.p7_vnfs[0].local_port = 50001; + //vnf.p7_vnfs[0].local_port = vnf.p7_vnfs[0].local_port; // 50001; // TODO: remove hardcode + vnf.p7_vnfs[0].local_port = 50011; vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t)); nfapi_vnf_config_t *config = nfapi_vnf_config_create(); config->malloc = malloc; @@ -1161,8 +1571,10 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { config->vnf_ipv6 = 0; config->pnf_list = 0; config->phy_list = 0; + config->pnf_connection_indication = &pnf_connection_indication_cb; config->pnf_disconnect_indication = &pnf_disconnection_indication_cb; + config->pnf_param_resp = &pnf_param_resp_cb; config->pnf_config_resp = &pnf_config_resp_cb; config->pnf_start_resp = &pnf_start_resp_cb; @@ -1203,15 +1615,17 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return retval; } -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_tti_request_t *dl_config_req) +int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { + //LOG_I(PHY, "sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot); + //printf("\nEntering oai_nfapi_nr_dl_config_req sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot); nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; - + dl_config_req->header.message_id= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST; dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! int retval = nfapi_vnf_p7_nr_dl_config_req(p7_config, dl_config_req); - dl_config_req->dl_tti_request_body.nPDUs = 0; + dl_config_req->dl_tti_request_body.nPDUs = 0; dl_config_req->dl_tti_request_body.nGroup = 0; @@ -1221,6 +1635,23 @@ int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_tti_request_t *dl_config_req) return retval; } +int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req) +{ + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + tx_data_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + tx_data_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST; + //LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_req->sfn_sf), tx_req->tx_request_body.number_of_pdus); + int retval = nfapi_vnf_p7_tx_data_req(p7_config, tx_data_req); + + if (retval!=0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + tx_data_req->Number_of_PDUs = 0; + } + + return retval; +} + int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; @@ -1238,6 +1669,22 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) return retval; } +int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req) { + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + ul_dci_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + ul_dci_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST; + //LOG_D(PHY, "[VNF] %s() HI_DCI0_REQ sfn_sf:%d dci:%d hi:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req->hi_dci0_request_body.number_of_dci, hi_dci0_req->hi_dci0_request_body.number_of_hi); + int retval = nfapi_vnf_p7_ul_dci_req(p7_config, ul_dci_req); + + if (retval!=0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + ul_dci_req->numPdus = 0; + } + + return retval; +} + int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; hi_dci0_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! @@ -1255,6 +1702,26 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return retval; } +int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req) { + nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; + + ul_tti_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! + ul_tti_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST; + + int retval = nfapi_vnf_p7_ul_tti_req(p7_config, ul_tti_req); + + if (retval!=0) { + LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); + } else { + // Reset number of PDUs so that it is not resent + ul_tti_req->n_pdus = 0; + ul_tti_req->n_group = 0; + ul_tti_req->n_ulcch = 0; + ul_tti_req->n_ulsch = 0; + } + return retval; +} + int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; ul_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! diff --git a/nfapi/oai_integration/nfapi_vnf.h b/nfapi/oai_integration/nfapi_vnf.h index 4ea26eda12..f4fd6a2bf9 100644 --- a/nfapi/oai_integration/nfapi_vnf.h +++ b/nfapi/oai_integration/nfapi_vnf.h @@ -23,5 +23,5 @@ #define NFAPI_VNF_H__ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port); - +void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port); #endif 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 9df9be4cbd..8c2118cd3d 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 @@ -972,7 +972,7 @@ typedef struct typedef struct { - uint32_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm) + int ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm) uint8_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload uint8_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index 32a31a99f6..0eb77a9d26 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -120,6 +120,17 @@ typedef struct { } nfapi_tl_t; #define NFAPI_TAG_LENGTH_PACKED_LEN 4 +// Convenience methods to convert between SFN/SLOT formats +#define NFAPI_SFNSLOT2DEC(_sfn,_slot) ( _sfn*20 + _slot ) // total count of slots +#define NFAPI_SFNSLOTDEC2SFNSLOT(_sfnslot_dec) ((((_sfnslot_dec) / 20) << 4) | (((_sfnslot_dec) - (((_sfnslot_dec) / 20) * 10)) & 0x3F)) + +#define NFAPI_SFNSLOT2SFN(_sfnslot) ((_sfnslot) >> 6) +#define NFAPI_SFNSLOT2SLOT(_sfnslot) ((_sfnslot) & 0x3F) +#define NFAPI_SFNSLOTDEC2SFN(_sfnslot_dec) ((_sfnslot_dec) / 20) +#define NFAPI_SFNSLOTDEC2SLOT(_sfnslot_dec) ((_sfnslot_dec) % 20) + +#define NFAPI_MAX_SFNSLOTDEC 1024*20 // 20 is for numerology 1 + // Convenience methods to convert between SFN/SFN formats #define NFAPI_SFNSF2DEC(_sfnsf) ((((_sfnsf) >> 4) * 10) + ((_sfnsf) & 0xF)) #define NFAPI_SFNSFDEC2SFNSF(_sfnsf_dec) ((((_sfnsf_dec) / 10) << 4) | (((_sfnsf_dec) - (((_sfnsf_dec) / 10) * 10)) & 0xF)) @@ -176,7 +187,6 @@ typedef enum { NFAPI_DL_NODE_SYNC, NFAPI_TIMING_INFO, - NFAPI_RSSI_REQUEST = 0x0200, NFAPI_RSSI_RESPONSE, NFAPI_RSSI_INDICATION, @@ -587,6 +597,26 @@ typedef struct { #define NFAPI_PNF_PHY_RF_TAG 0x1003 // Generic strucutre for single tlv value. +typedef struct { + nfapi_tl_t tl; + int32_t value; +} nfapi_int32_tlv_t; + +typedef struct { + nfapi_tl_t tl; + uint32_t value; +} nfapi_uint32_tlv_t; + +typedef struct { + nfapi_tl_t tl; + int64_t value; +} nfapi_int64_tlv_t; + +typedef struct { + nfapi_tl_t tl; + uint64_t value; +} nfapi_uint64_tlv_t; + typedef struct { nfapi_tl_t tl; uint16_t value; @@ -1106,6 +1136,7 @@ typedef struct { typedef struct { nfapi_p4_p5_message_header_t header; + uint8_t num_tlvs; nfapi_pnf_phy_rf_config_t pnf_phy_rf_config; nfapi_vendor_extension_tlv_t vendor_extension; } nfapi_pnf_config_request_t; @@ -2466,7 +2497,7 @@ typedef struct { typedef struct { nfapi_p7_message_header_t header; uint32_t t1; - int32_t delta_sfn_sf; + int32_t delta_sfn_sf; nfapi_vendor_extension_tlv_t vendor_extension; } nfapi_dl_node_sync_t; @@ -2481,22 +2512,50 @@ typedef struct { typedef struct { nfapi_p7_message_header_t header; uint32_t last_sfn_sf; + uint32_t time_since_last_timing_info; uint32_t dl_config_jitter; uint32_t tx_request_jitter; uint32_t ul_config_jitter; uint32_t hi_dci0_jitter; + int32_t dl_config_latest_delay; int32_t tx_request_latest_delay; int32_t ul_config_latest_delay; int32_t hi_dci0_latest_delay; + int32_t dl_config_earliest_arrival; int32_t tx_request_earliest_arrival; int32_t ul_config_earliest_arrival; int32_t hi_dci0_earliest_arrival; + nfapi_vendor_extension_tlv_t vendor_extension; } nfapi_timing_info_t; +typedef struct { + nfapi_p7_message_header_t header; + + uint32_t last_sfn; + uint32_t last_slot; + uint32_t time_since_last_timing_info; + + uint32_t dl_tti_jitter; + uint32_t tx_data_request_jitter; + uint32_t ul_tti_jitter; + uint32_t ul_dci_jitter; + + int32_t dl_tti_latest_delay; + int32_t tx_data_request_latest_delay; + int32_t ul_tti_latest_delay; + int32_t ul_dci_latest_delay; + + int32_t dl_tti_earliest_arrival; + int32_t tx_data_request_earliest_arrival; + int32_t ul_tti_earliest_arrival; + int32_t ul_dci_earliest_arrival; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_timing_info_t; + typedef struct { nfapi_tl_t tl; uint32_t handle; @@ -3653,6 +3712,50 @@ typedef struct { nfapi_vendor_extension_tlv_t vendor_extension; } nfapi_nmm_stop_response_t; +typedef struct +{ + // TODO: see if this needs to be uncommented + + // These TLVs are used to setup the transport connection between VNF and PNF + nfapi_ipv4_address_t p7_vnf_address_ipv4; + nfapi_ipv6_address_t p7_vnf_address_ipv6; + nfapi_uint16_tlv_t p7_vnf_port; + + nfapi_ipv4_address_t p7_pnf_address_ipv4; + nfapi_ipv6_address_t p7_pnf_address_ipv6; + nfapi_uint16_tlv_t p7_pnf_port; + + nfapi_uint8_tlv_t timing_window; //Value: 0 → 30,000 microseconds + nfapi_uint8_tlv_t timing_info_mode; + nfapi_uint8_tlv_t timing_info_period; + + nfapi_uint32_tlv_t dl_tti_timing_offset; + nfapi_uint32_tlv_t ul_tti_timing_offset; + nfapi_uint32_tlv_t ul_dci_timing_offset; + nfapi_uint32_tlv_t tx_data_timing_offset; + + // These TLVs are used to setup the transport connection between VNF and PNF + /* + nfapi_uint8_tlv_t dl_ue_per_sf; + nfapi_uint8_tlv_t ul_ue_per_sf; + + // These TLVs are used by PNF to report its RF capabilities to the VNF software + nfapi_rf_bands_t rf_bands; +*/ + // These TLVs are used by the VNF to configure the synchronization with the PNF. + + + // These TLVs are used by the VNF to configure the RF in the PNF + //nfapi_uint16_tlv_t max_transmit_power; + //nfapi_uint32_tlv_t nrarfcn; + + // nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands; + // nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands; + // nfapi_nmm_frequency_bands_t nmm_lte_frequency_bands; + // nfapi_uint8_tlv_t nmm_uplink_rssi_supported; + +} nfapi_nr_nfapi_t; + // // Configuration options for the encode decode functions // @@ -3864,6 +3967,7 @@ int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn * */ int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config); +int nfapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config); /*! \brief Decodes an NFAPI P5 message header * \param pMessageBuf A pointer to an encoded P5 message header @@ -3887,6 +3991,7 @@ int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo * * The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf */ +int nfapi_nr_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config); int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config); /*! \brief Encodes an NFAPI P7 message to a buffer @@ -3900,6 +4005,7 @@ int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn * */ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config); +int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config); /*! \brief Decodes an NFAPI P7 message header * \param pMessageBuf A pointer to an encoded P7 message header @@ -3925,6 +4031,7 @@ int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo * The function will decode a byte stream pointed to by pMessageBuf into a nfapi p7 message structure pointer to by pUnpackedBuf */ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config); +int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config); /*! \brief Calculates the checksum of a message * diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h index 650bda4f78..fbe7a0e170 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -10,7 +10,7 @@ #define _NFAPI_NR_INTERFACE_H_ #include "nfapi_interface.h" -#include +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" #define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5 #define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64 @@ -22,62 +22,32 @@ // nFAPI enums - //These TLVs are used exclusively by nFAPI -typedef struct -{ - // These TLVs are used to setup the transport connection between VNF and PNF - // nfapi_ipv4_address_t p7_vnf_address_ipv4; - // nfapi_ipv6_address_t p7_vnf_address_ipv6; - // nfapi_uint16_tlv_t p7_vnf_port; - - // nfapi_ipv4_address_t p7_pnf_address_ipv4; - // nfapi_ipv6_address_t p7_pnf_address_ipv6; - // nfapi_uint16_tlv_t p7_pnf_port; - - // // These TLVs are used to setup the transport connection between VNF and PNF - // nfapi_uint8_tlv_t dl_ue_per_sf; - // nfapi_uint8_tlv_t ul_ue_per_sf; - - // These TLVs are used by PNF to report its RF capabilities to the VNF software - nfapi_rf_bands_t rf_bands; - - // These TLVs are used by the VNF to configure the synchronization with the PNF. - // nfapi_uint8_tlv_t timing_window; - // nfapi_uint8_tlv_t timing_info_mode; - // nfapi_uint8_tlv_t timing_info_period; - - // These TLVs are used by the VNF to configure the RF in the PNF - // nfapi_uint16_tlv_t max_transmit_power; - nfapi_uint32_tlv_t nrarfcn; - - // nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands; - // nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands; - // nfapi_nmm_frequency_bands_t nmm_lte_frequency_bands; - // nfapi_uint8_tlv_t nmm_uplink_rssi_supported; - -} nfapi_nr_nfapi_t; - -#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x5100 -#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x5101 -#define NFAPI_NR_NFAPI_P7_VNF_PORT_TAG 0x5102 -#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG 0x5103 -#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG 0x5104 -#define NFAPI_NR_NFAPI_P7_PNF_PORT_TAG 0x5105 +#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x0100 +#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x0101 +#define NFAPI_NR_NFAPI_P7_VNF_PORT_TAG 0x0102 +#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG 0x0103 +#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG 0x0104 +#define NFAPI_NR_NFAPI_P7_PNF_PORT_TAG 0x0105 +#define NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET 0x0106 +#define NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET 0x0107 +#define NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET 0x0108 +#define NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET 0x0109 +#define NFAPI_NR_NFAPI_TIMING_WINDOW_TAG 0x011E +#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x011F +#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x0120 +/* #define NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG 0x510A #define NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG 0x510B #define NFAPI_NR_NFAPI_RF_BANDS_TAG 0x5114 -#define NFAPI_NR_NFAPI_TIMING_WINDOW_TAG 0x511E -#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x511F -#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x5120 #define NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG 0x5128 #define NFAPI_NR_NFAPI_NRARFCN_TAG 0x5129 #define NFAPI_NR_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG 0x5130 #define NFAPI_NR_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG 0x5131 #define NFAPI_NR_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG 0x5132 #define NFAPI_NR_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG 0x5133 - +*/ // P5 Message Structures typedef struct { @@ -323,7 +293,7 @@ typedef enum { typedef enum { NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED=0, - NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED + NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED=1 } nfapi_nr_cce_reg_mapping_type_e; typedef enum { diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf new file mode 100644 index 0000000000..6ee4ec8404 Binary files /dev/null and b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf differ 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 12748b7a9e..444140509c 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 @@ -11,6 +11,7 @@ #include "stddef.h" #include "nfapi_interface.h" +#include "nfapi_nr_interface.h" #define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5 #define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64 @@ -24,25 +25,7 @@ #define NFAPI_MAX_NUM_CB 8 // Extension to the generic structures for single tlv values -typedef struct { - nfapi_tl_t tl; - int32_t value; -} nfapi_int32_tlv_t; -typedef struct { - nfapi_tl_t tl; - uint32_t value; -} nfapi_uint32_tlv_t; - -typedef struct { - nfapi_tl_t tl; - int64_t value; -} nfapi_int64_tlv_t; - -typedef struct { - nfapi_tl_t tl; - uint64_t value; -} nfapi_uint64_tlv_t; typedef enum { NFAPI_NR_DMRS_TYPE1=0, @@ -76,35 +59,42 @@ typedef enum { NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST= 0X05, NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION=0X06, NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION=0X07, + NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE=0X010D, + NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE=0X010F, //RESERVED 0X08 ~ 0X7F NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST= 0X80, NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST= 0X81, NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION=0X82, NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST= 0X83, - NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X54, + NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X84, // CHANGED TO 0X84 NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION=0X85, NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION= 0X86, NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION= 0X87, NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION= 0X88, - NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89 + NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89, //RESERVED 0X8a ~ 0xff + NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST = 0x0100, + NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE = 0x0101, + NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST= 0x0102, + NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE= 0x0103, + NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST= 0x0104, + NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE= 0x0105, + NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST= 0x0106, + NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE= 0x0107, + + NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC = 0x0180, + NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC, + NFAPI_NR_PHY_MSG_TYPE_TIMING_INFO } nfapi_nr_phy_msg_type_e; // SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.3 //3.3.1 PARAM + + //same with nfapi_param_request_t -typedef struct { - nfapi_p4_p5_message_header_t header; - nfapi_vendor_extension_tlv_t vendor_extension; -} nfapi_nr_param_request_t; -typedef enum { - NFAPI_NR_PARAM_MSG_OK = 0, - NFAPI_NR_PARAM_MSG_INVALID_STATE - -} nfapi_nr_param_errors_e; /*typedef struct { nfapi_nr_param_errors_e error_code; @@ -278,12 +268,6 @@ typedef struct //-------------------------------------------// //3.3.2 CONFIG - -typedef enum { - NFAPI_NR_CONFIG_MSG_OK = 0, - NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state. -} nfapi_nr_config_errors_e; - /*typedef struct { nfapi_nr_config_errors_e error_code; uint8_t number_of_invalid_tlvs_that_can_only_be_configured_in_idle; @@ -373,7 +357,7 @@ typedef struct //table 3-23 typedef struct { - nfapi_uint32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm) + nfapi_int32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm) nfapi_uint8_tlv_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload nfapi_uint8_tlv_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3 @@ -414,13 +398,13 @@ typedef struct { nfapi_uint32_tlv_t ssb_mask;//Bitmap for actually transmitted SSB. MSB->LSB of first 32 bit number corresponds to SSB 0 to SSB 31 MSB->LSB of second 32 bit number corresponds to SSB 32 to SSB 63 Value for each bit: 0: not transmitted 1: transmitted -} nfapi_nr_ssb_mask_size_2_t; +} nfapi_nr_ssb_mask_list_t; typedef struct { - nfapi_uint8_tlv_t beam_id[64];//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63 + nfapi_uint8_tlv_t beam_id;//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63 -} nfapi_nr_ssb_mask_size_64_t; +} nfapi_nr_ssb_beam_id_list_t; typedef struct { @@ -429,8 +413,8 @@ typedef struct nfapi_uint8_tlv_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160 nfapi_uint8_tlv_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31 nfapi_uint32_tlv_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1] - nfapi_nr_ssb_mask_size_2_t ssb_mask_list[2]; - nfapi_nr_ssb_mask_size_64_t* ssb_beam_id_list;//64 + nfapi_nr_ssb_mask_list_t ssb_mask_list[2]; + nfapi_nr_ssb_beam_id_list_t ssb_beam_id_list[64]; nfapi_uint8_tlv_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled nfapi_uint8_tlv_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled @@ -465,9 +449,108 @@ typedef struct } nfapi_nr_measurement_config_t; +// ERROR enums +typedef enum { // Table 2-22 + NFAPI_NR_PARAM_MSG_OK = 0, + NFAPI_NR_PARAM_MSG_INVALID_STATE +} nfapi_nr_param_errors_e; + +typedef enum { // Table 2-25 + NFAPI_NR_CONFIG_MSG_OK = 0, + NFAPI_NR_CONFIG_MSG_INVALID_STATE, //The CONFIG.request was received when the PHY was not in the IDLE state or the CONFIGURED state. + NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state. +} nfapi_nr_config_errors_e; + +typedef enum { // Table 2-27 + NFAPI_NR_START_MSG_OK = 0, + NFAPI_NR_START_MSG_INVALID_STATE +} nfapi_nr_start_errors_e; + +//PNF P5 NR +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_pnf_param_request_t; typedef struct { - uint8_t num_tlv; + nfapi_p4_p5_message_header_t header; + uint32_t error_code; + nfapi_pnf_param_general_t pnf_param_general; + nfapi_pnf_phy_t pnf_phy; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_pnf_param_response_t; + +typedef struct { + nfapi_p4_p5_message_header_t header; + uint8_t num_tlvs; + nfapi_pnf_phy_rf_config_t pnf_phy_rf_config; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_pnf_config_request_t; + +typedef struct { + nfapi_p4_p5_message_header_t header; + uint32_t error_code; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_pnf_config_response_t; + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_pnf_start_request_t; + +typedef struct { + nfapi_p4_p5_message_header_t header; + uint32_t error_code; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_pnf_start_response_t; + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_pnf_stop_request_t; + +typedef struct { + nfapi_p4_p5_message_header_t header; + uint32_t error_code; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_pnf_stop_response_t; + + +/* PARAM.REQUEST */ +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_param_request_scf_t; + +/* PARAM.RESPONSE */ +typedef struct { + nfapi_p4_p5_message_header_t header; + uint8_t error_code; + + uint8_t num_tlv; + nfapi_vendor_extension_tlv_t vendor_extension; + + nfapi_nr_cell_param_t cell_param; + nfapi_nr_carrier_param_t carrier_param; + nfapi_nr_pdcch_param_t pdcch_param; + nfapi_nr_pucch_param_t pucch_param; + nfapi_nr_pdsch_param_t pdsch_param; + nfapi_nr_pusch_param_t pusch_param; + nfapi_nr_prach_param_t prach_param; + nfapi_nr_measurement_param_t measurement_param; + nfapi_nr_nfapi_t nfapi_config; +} nfapi_nr_param_response_scf_t; + +//------------------------------// +//3.3.2 CONFIG + +/* CONFIG.REQUEST */ +typedef struct { + nfapi_p4_p5_message_header_t header; + + uint8_t num_tlv; + nfapi_vendor_extension_tlv_t vendor_extension; + nfapi_nr_carrier_config_t carrier_config; nfapi_nr_cell_config_t cell_config; nfapi_nr_ssb_config_t ssb_config; @@ -475,20 +558,32 @@ typedef struct { nfapi_nr_ssb_table_t ssb_table; nfapi_nr_tdd_table_t tdd_table; nfapi_nr_measurement_config_t measurement_config; + nfapi_nr_nfapi_t nfapi_config; } nfapi_nr_config_request_scf_t; +/* CONFIG.RESPONSE */ +typedef struct { + nfapi_p4_p5_message_header_t header; + uint8_t error_code; + //uint8_t num_invalid_tlvs; + // TODO: add list of invalid/unsupported TLVs (see Table 3.18) + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_config_response_scf_t; + //------------------------------// //3.3.3 START typedef struct { nfapi_p4_p5_message_header_t header; nfapi_vendor_extension_tlv_t vendor_extension; -} nfapi_nr_start_request_t; +} nfapi_nr_start_request_scf_t; -typedef enum { - NFAPI_NR_START_MSG_INVALID_STATE -} nfapi_nr_start_errors_e; +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_nr_start_errors_e error_code; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_start_response_scf_t; //3.3.4 STOP @@ -497,6 +592,7 @@ typedef struct { nfapi_vendor_extension_tlv_t vendor_extension; } nfapi_nr_stop_request_t; + typedef struct { nfapi_p4_p5_message_header_t header; nfapi_vendor_extension_tlv_t vendor_extension; @@ -580,9 +676,9 @@ typedef struct { uint16_t sfn; //0->1023 uint16_t slot;//0->319 -} nfapi_nr_slot_indication_t; +} nfapi_nr_slot_indication_scf_t; -// 3.4.2 +// 3.4.2 //for pdcch_pdu: @@ -595,11 +691,10 @@ typedef struct typedef struct { uint16_t pm_idx;//Index to precoding matrix (PM) pre-stored at cell configuration. Note: If precoding is not used this parameter should be set to 0. Value: 0->65535. - nfapi_nr_dig_bf_interface_t* dig_bf_interface_list; + nfapi_nr_dig_bf_interface_t dig_bf_interface_list[255];//max dig_bf_interfaces }nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t; -/* //table 3-43 typedef struct { @@ -607,21 +702,10 @@ typedef struct uint16_t prg_size;//Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 //watchout: dig_bf_interfaces here, in table 3-53 it's dig_bf_interface uint8_t dig_bf_interfaces;//Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 - nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t* prgs_list;// + nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t prgs_list[275];//max prg_size }nfapi_nr_tx_precoding_and_beamforming_t; -*/ -typedef struct { - /// Number of PRGs spanning this allocation. Value : 1->275 - uint16_t numPRGs; - /// Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 - uint16_t prgSize; - /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 - uint8_t digBFInterfaces; - uint16_t PMIdx[275]; - uint16_t *beamIdx[275]; -} nfapi_nr_tx_precoding_and_beamforming_t; //table 3-37 @@ -657,16 +741,6 @@ typedef struct { } nfapi_nr_dl_dci_pdu_t; -typedef struct { - /// Number of PRGs spanning this allocation. Value : 1->275 - uint16_t numPRGs; - /// Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 - uint16_t prgSize; - /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 - uint8_t digBFInterfaces; - uint16_t PMIdx[275]; - uint16_t *beamIdx[275]; -} nr_beamforming_t; typedef struct { ///Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP,Value: 1->275 @@ -930,7 +1004,7 @@ typedef struct { typedef struct { uint16_t PDUType; - uint16_t PDUSize; + uint32_t PDUSize; union { nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu; @@ -941,6 +1015,7 @@ typedef struct { } nfapi_nr_dl_tti_request_pdu_t; #define NFAPI_NR_MAX_DL_TTI_PDUS 32 + typedef struct { /// Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255 uint8_t nPDUs; @@ -954,11 +1029,28 @@ typedef struct { uint8_t PduIdx[256][12]; } nfapi_nr_dl_tti_request_body_t; + +typedef struct { + nfapi_p7_message_header_t header; + uint32_t t1; + int32_t delta_sfn_slot; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_dl_node_sync_t; + +typedef struct { + nfapi_p7_message_header_t header; + uint32_t t1; + uint32_t t2; + uint32_t t3; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_ul_node_sync_t; + + typedef struct { nfapi_p7_message_header_t header; /// System Frame Number (0-1023) uint16_t SFN; - /// Slot number (0-319) + /// Slot number (0-19) uint16_t Slot; nfapi_nr_dl_tti_request_body_t dl_tti_request_body; nfapi_vendor_extension_tlv_t vendor_extension; @@ -973,7 +1065,7 @@ typedef struct nfapi_nr_dl_tti_ssb_pdu_t* ssb_pdu; } nfapi_nr_dl_pdu_configuration_t; */ - /* + /* typedef struct { uint16_t pdu_type;//0: PDCCH PDU 1: PDSCH PDU 2: CSI-RS PDU 3: SSB PDU, @@ -1272,6 +1364,7 @@ typedef struct } nfapi_nr_ul_tti_request_number_of_groups_t; typedef struct { + nfapi_p7_message_header_t header; uint16_t SFN; //0->1023 uint16_t Slot;//0->319 uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255 @@ -1318,6 +1411,7 @@ typedef struct { } nfapi_nr_ul_dci_request_pdus_t; typedef struct { + nfapi_p7_message_header_t header; uint16_t SFN; uint16_t Slot; uint8_t numPdus; @@ -1363,6 +1457,7 @@ typedef struct #define NFAPI_NR_MAX_TX_REQUEST_PDUS 16 typedef struct { + nfapi_p7_message_header_t header; uint16_t SFN; uint16_t Slot; uint16_t Number_of_PDUs; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c index 61c6875bc6..ba800c3634 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c @@ -712,7 +712,7 @@ int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPa for(idx = 0; idx < size; ++idx) { - if(unpack_fns[idx].tag == generic_tl.tag) + if(unpack_fns[idx].tag == generic_tl.tag) // match the extracted tag value with all the tags in unpack_fn list { tagMatch = 1; nfapi_tl_t* tl = (nfapi_tl_t*)(unpack_fns[idx].tlv); diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c index a8ac0f0a65..8aea9f590c 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c @@ -33,10 +33,18 @@ #include #include +#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include // Pack routines +//TODO: Add pacl/unpack fns for uint32 and uint64 +static uint8_t pack_nr_pnf_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_param_request_t* request = (nfapi_nr_pnf_param_request_t*)msg; + return pack_vendor_extension_tlv(request->vendor_extension, ppWritePackedMsg, end, config); +} static uint8_t pack_pnf_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) { @@ -233,6 +241,26 @@ static uint8_t pack_pnf_phy_rel13_nb_iot_value(void* tlv, uint8_t **ppWritePacke return (push16(value->number_of_phys, ppWritePackedMsg, end) && packarray(value->phy, sizeof(nfapi_pnf_phy_rel13_nb_iot_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_info)); } +/* +static uint8_t pack_nr_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) && + pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} +*/ +static uint8_t pack_nr_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t*)msg; + + return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) && + pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} static uint8_t pack_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) @@ -251,6 +279,7 @@ static uint8_t pack_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, ui pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); } + static uint8_t pack_phy_rf_config_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_phy_rf_config_info_t* rf = (nfapi_phy_rf_config_info_t*)elem; @@ -270,11 +299,29 @@ static uint8_t pack_pnf_phy_rf_config_value(void *tlv, uint8_t **ppWritePackedMs } +static uint8_t pack_nr_pnf_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_config_request_t *pNfapiMsg = (nfapi_nr_pnf_config_request_t*)msg; + return (pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) && + //push8(pNfapiMsg->num_tlvs,ppWritePackedMsg,end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end , config)); +} + static uint8_t pack_pnf_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_config_request_t *pNfapiMsg = (nfapi_pnf_config_request_t*)msg; - return ( pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) && - pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end , config)); + return (pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) && + push8(pNfapiMsg->num_tlvs,ppWritePackedMsg,end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end , config)); +} + + +static uint8_t pack_nr_pnf_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_config_response_t *pNfapiMsg = (nfapi_nr_pnf_config_response_t*)msg; + + return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); } @@ -286,12 +333,28 @@ static uint8_t pack_pnf_config_response(void *msg, uint8_t **ppWritePackedMsg, u pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); } +static uint8_t pack_nr_pnf_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_start_request_t *pNfapiMsg = (nfapi_nr_pnf_start_request_t*)msg; + return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + static uint8_t pack_pnf_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_start_request_t *pNfapiMsg = (nfapi_pnf_start_request_t*)msg; return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); } + +static uint8_t pack_nr_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_start_response_t *pNfapiMsg = (nfapi_nr_pnf_start_response_t*)msg; + + return( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + + static uint8_t pack_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_start_response_t *pNfapiMsg = (nfapi_pnf_start_response_t*)msg; @@ -300,12 +363,31 @@ static uint8_t pack_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, ui pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); } + +static uint8_t pack_nr_pnf_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_stop_request_t *pNfapiMsg = (nfapi_nr_pnf_stop_request_t*)msg; + return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); +} + + + static uint8_t pack_pnf_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_stop_request_t *pNfapiMsg = (nfapi_pnf_stop_request_t*)msg; return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); } + +static uint8_t pack_nr_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_stop_response_t *pNfapiMsg = (nfapi_nr_pnf_stop_response_t*)msg; + + return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + + static uint8_t pack_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_stop_response_t *pNfapiMsg = (nfapi_pnf_stop_response_t*)msg; @@ -314,12 +396,31 @@ static uint8_t pack_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uin pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); } +static uint8_t pack_nr_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_param_request_scf_t *pNfapiMsg = (nfapi_nr_param_request_scf_t*)msg; + return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + static uint8_t pack_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) -{ +{ nfapi_param_request_t *pNfapiMsg = (nfapi_param_request_t*)msg; return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); } +static uint8_t pack_uint32_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_uint32_tlv_t* value = (nfapi_uint32_tlv_t*)tlv; + return push32(value->value, ppWritePackedMsg, end); +} + +static uint8_t unpack_uint32_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_uint32_tlv_t* value = (nfapi_uint32_tlv_t*)tlv; + return pull32(ppReadPackedMsg, &value->value, end); +} + + static uint8_t pack_uint16_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_uint16_tlv_t* value = (nfapi_uint16_tlv_t*)tlv; @@ -331,6 +432,7 @@ static uint8_t unpack_uint16_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uin nfapi_uint16_tlv_t* value = (nfapi_uint16_tlv_t*)tlv; return pull16(ppReadPackedMsg, &value->value, end); } + static uint8_t pack_int16_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_int16_tlv_t* value = (nfapi_int16_tlv_t*)tlv; @@ -414,18 +516,19 @@ static uint8_t pack_embms_mbsfn_config_value(void* tlv, uint8_t **ppWritePackedM pusharray8(value->fourframes_flag, 8,value->num_mbsfn_config,ppWritePackedMsg, end) && pusharrays32(value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, ppWritePackedMsg, end)); } -//static uint8_t unpack_embms_mbsfn_config_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t* end) -//{ +// static uint8_t unpack_embms_mbsfn_config_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t* end) +// { // nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv; -// + // return ( pull16(ppReadPackedMsg, &value->num_mbsfn_config, end) && // pull16(ppReadPackedMsg, &value->radioframe_allocation_period, end) && // pull16(ppReadPackedMsg, &value->radioframe_allocation_offset, end) && // pull8(ppReadPackedMsg, &value->fourframes_flag, end) && // pullarrays32(ppReadPackedMsg, value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, end)); -//} -static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) -{ +// } + +static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config) +{ nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t*)msg; return( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) && @@ -536,6 +639,92 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_ } +static uint8_t pack_nr_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + printf("\nRUNNING pack_param_response\n"); + nfapi_nr_param_response_scf_t *pNfapiMsg = (nfapi_nr_param_response_scf_t*)msg; + + return (push8(pNfapiMsg->error_code, ppWritePackedMsg, end) && + push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) && + pack_tlv(NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->cell_param.release_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PHY_STATE_TAG, &(pNfapiMsg->cell_param.phy_state), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_dl_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_ul_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG, &(pNfapiMsg->cell_param.num_config_tlvs_to_report ), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG, &(pNfapiMsg->carrier_param.cyclic_prefix), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_dl), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_dl), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_ul), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG, &(pNfapiMsg->pdcch_param.cce_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG, &(pNfapiMsg->pdcch_param.coreset_outside_first_3_of_ofdm_syms_of_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG, &(pNfapiMsg->pdcch_param.coreset_precoder_granularity_coreset), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG, &(pNfapiMsg->pdcch_param.pdcch_mu_mimo), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG, &(pNfapiMsg->pdcch_param.pdcch_precoder_cycling), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG, &(pNfapiMsg->pdcch_param.max_pdcch_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG, &(pNfapiMsg->pucch_param.pucch_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG, &(pNfapiMsg->pucch_param.max_pucchs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pdsch_param.pdsch_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_allocation_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pdsch_param.pdsch_vrb_to_prb_mapping), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG, &(pNfapiMsg->pdsch_param.pdsch_cbg), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_config_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_max_length), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_additional_pos), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG, &(pNfapiMsg->pdsch_param.max_pdsch_tbs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG, &(pNfapiMsg->pdsch_param.max_number_mimo_layers_pdsch), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG, &(pNfapiMsg->pdsch_param.max_mu_mimo_users_dl), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG, &(pNfapiMsg->pdsch_param.pdsch_data_in_dmrs_symbols), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.premption_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.pdsch_non_slot_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_mux_ulsch_in_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_only_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG, &(pNfapiMsg->pusch_param.pusch_frequency_hopping), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_config_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_max_len), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_additional_pos), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG, &(pNfapiMsg->pusch_param.pusch_cbg), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pusch_param.pusch_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_allocation_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pusch_param.pusch_vrb_to_prb_mapping), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG, &(pNfapiMsg->pusch_param.pusch_max_ptrs_ports), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG, &(pNfapiMsg->pusch_param.max_pduschs_tbs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG, &(pNfapiMsg->pusch_param.max_number_mimo_layers_non_cb_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG, &(pNfapiMsg->pusch_param.supported_modulation_order_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG, &(pNfapiMsg->pusch_param.max_mu_mimo_users_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG, &(pNfapiMsg->pusch_param.dfts_ofdm_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG, &(pNfapiMsg->pusch_param.pusch_aggregation_factor), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_long_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_short_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG, &(pNfapiMsg->prach_param.prach_restricted_sets), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG, &(pNfapiMsg->prach_param.max_prach_fd_occasions_in_a_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG, &(pNfapiMsg->measurement_param.rssi_measurement_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + // config: + + pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && + pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && + + pack_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && + pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && + + pack_tlv(NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} + static uint8_t pack_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { nfapi_config_request_t *pNfapiMsg = (nfapi_config_request_t*)msg; @@ -668,20 +857,108 @@ static uint8_t pack_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); } + +static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + printf("\n\nEntering pack_config_request\n"); + nfapi_nr_config_request_scf_t *pNfapiMsg = (nfapi_nr_config_request_scf_t*)msg; + + + return (push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) && + pack_tlv(NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.dl_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_DL_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.dl_frequency), ppWritePackedMsg, end, &pack_uint32_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.dl_grid_size[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_DL_K0_TAG, &(pNfapiMsg->carrier_config.dl_k0[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_NUM_RX_ANT_TAG, &(pNfapiMsg->carrier_config.num_rx_ant), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_NUM_TX_ANT_TAG, &(pNfapiMsg->carrier_config.num_tx_ant), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.ul_grid_size[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_UL_K0_TAG, &(pNfapiMsg->carrier_config.ul_k0[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.uplink_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.uplink_frequency), ppWritePackedMsg, end, &pack_uint32_tlv_value) && + + pack_tlv(NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, &(pNfapiMsg->cell_config.frame_duplex_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_PHY_CELL_ID_TAG, &(pNfapiMsg->cell_config.phy_cell_id), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG, &(pNfapiMsg->prach_config.prach_sequence_length), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG, &(pNfapiMsg->prach_config.restricted_set_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_SSB_PER_RACH_TAG, &(pNfapiMsg->prach_config.ssb_per_rach), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG, &(pNfapiMsg->prach_config.prach_sub_c_spacing), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_K1_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].k1), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_zero_corr_conf), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].num_root_sequences), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + + pack_tlv(NFAPI_NR_CONFIG_SCS_COMMON_TAG, &(pNfapiMsg->ssb_config.scs_common), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, &(pNfapiMsg->ssb_config.ss_pbch_power), ppWritePackedMsg, end, &pack_uint32_tlv_value) && + + pack_tlv(NFAPI_NR_CONFIG_BETA_PSS_TAG, &(pNfapiMsg->ssb_table.beta_pss), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), ppWritePackedMsg, end, &pack_uint32_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask), ppWritePackedMsg, end, &pack_uint32_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[1].ssb_mask), ppWritePackedMsg, end, &pack_uint32_tlv_value) && + + pack_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, &(pNfapiMsg->ssb_table.ssb_offset_point_a), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG, &(pNfapiMsg->ssb_table.ssb_subcarrier_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG, &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[0].max_num_of_symbol_per_slot_list[0].slot_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + //pack_tlv(NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + //pack_tlv(NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + //pack_tlv(NFAPI_NR_NFAPI_NRARFCN_TAG, &(pNfapiMsg->nfapi_config.nrarfcn), ppWritePackedMsg, end, &pack_uint32_tlv_value) && + pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && + pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && + pack_tlv(NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && + pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && + pack_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + //pack_tlv(NFAPI_NR_NFAPI_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) && + pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + //pack_tlv(NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); +} + +static uint8_t pack_nr_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_config_response_scf_t *pNfapiMsg = (nfapi_nr_config_response_scf_t*)msg; + + return ( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); +} + static uint8_t pack_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { nfapi_config_response_t *pNfapiMsg = (nfapi_config_response_t*)msg; - return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) && + return ( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) && pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); } +static uint8_t pack_nr_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_start_request_scf_t *pNfapiMsg = (nfapi_nr_start_request_scf_t*)msg; + return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); +} + static uint8_t pack_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { nfapi_start_request_t *pNfapiMsg = (nfapi_start_request_t*)msg; return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); } +static uint8_t pack_nr_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_start_response_scf_t *pNfapiMsg = (nfapi_nr_start_response_scf_t*)msg; + + return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end ) && + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); +} + static uint8_t pack_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { nfapi_start_response_t *pNfapiMsg = (nfapi_start_response_t*)msg; @@ -690,6 +967,7 @@ static uint8_t pack_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); } + static uint8_t pack_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { nfapi_stop_request_t *pNfapiMsg = (nfapi_stop_request_t*)msg; @@ -733,6 +1011,101 @@ static uint8_t pack_measurement_response(void *msg, uint8_t **ppWritePackedMsg, pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); } +static uint8_t pack_nr_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +{ + uint8_t result = 0; + // look for the specific message + switch (header->message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST: + result = pack_nr_pnf_param_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PNF_PARAM_RESPONSE: + result = pack_nr_pnf_param_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST: + result = pack_nr_pnf_config_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE: + result = pack_nr_pnf_config_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST: + result = pack_nr_pnf_start_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE: + result = pack_nr_pnf_start_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST: + result = pack_nr_pnf_stop_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_PNF_STOP_RESPONSE: + result = pack_nr_pnf_stop_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST: + result = pack_nr_param_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE: + result = pack_nr_param_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST: + result = pack_nr_config_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: + result = pack_nr_config_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST: + result = pack_nr_start_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE: + result = pack_nr_start_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST: + result = pack_stop_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE: + result = pack_stop_response(header, ppWritePackedMsg, end, config); + break; + default: + { + if(header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->pack_p4_p5_vendor_extension) + { + result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id); + } + } + break; + } + + return result; +} + + static uint8_t pack_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { uint8_t result = 0; @@ -852,6 +1225,55 @@ static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) } // Main pack function - public +int nfapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf; + uint8_t *pWritePackedMessage = pPackedBuf; + uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen; + uint8_t *pPackedLengthField = &pWritePackedMessage[4]; + uint32_t packedMsgLen; + uint16_t packedMsgLen16; + + if (pMessageBuf == NULL || pPackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n"); + return -1; + } + + // pack the message + if(push16(pMessageHeader->phy_id, &pWritePackedMessage, pPackMessageEnd) && + push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd) && + push16(0, &pWritePackedMessage, pPackMessageEnd) && + push16(pMessageHeader->spare, &pWritePackedMessage, pPackMessageEnd) && + pack_nr_p5_message_body(pMessageHeader, &pWritePackedMessage, pPackMessageEnd, config)) + { + // check for a valid message length + packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pWritePackedMessage); + if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen); + return -1; + } + else + { + packedMsgLen16 = (uint16_t)packedMsgLen; + } + + // Update the message length in the header + if(!push16(packedMsgLen16, &pPackedLengthField, pPackMessageEnd)) + return -1; + + // return the packed length + return (packedMsgLen); + } + else + { + // Failed to pack the meassage + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n"); + return -1; + } + +} int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config) { @@ -906,6 +1328,20 @@ int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPack // Unpack routines + + +static uint8_t unpack_nr_pnf_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_param_request_t *pNfapiMsg = (nfapi_nr_pnf_param_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); +} + + static uint8_t unpack_pnf_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_param_request_t *pNfapiMsg = (nfapi_pnf_param_request_t*)msg; @@ -1108,6 +1544,20 @@ static uint8_t unpack_pnf_phy_rel13_nb_iot_value(void* tlv, uint8_t **ppReadPack unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel13_nb_iot_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel13_nb_info_info)); } +static uint8_t unpack_nr_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, &unpack_pnf_param_general_value}, + { NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, &unpack_pnf_phy_value}, + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + static uint8_t unpack_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) @@ -1124,12 +1574,14 @@ static uint8_t unpack_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end { NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, &unpack_pnf_phy_rel12_value}, { NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, &unpack_pnf_phy_rel13_value}, { NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, &unpack_pnf_phy_rel13_nb_iot_value}, + }; return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); } + static uint8_t unpack_phy_rf_config_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end) { nfapi_phy_rf_config_info_t* rf = (nfapi_phy_rf_config_info_t*)elem; @@ -1148,6 +1600,20 @@ static uint8_t unpack_pnf_phy_rf_config_value(void* tlv, uint8_t **ppReadPackedM unpackarray(ppReadPackedMsg, value->phy_rf_config, sizeof(nfapi_phy_rf_config_info_t), NFAPI_MAX_PHY_RF_INSTANCES, value->number_phy_rf_config_info, end, &unpack_phy_rf_config_info)); } +static uint8_t unpack_nr_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_config_request_t *pNfapiMsg = (nfapi_nr_pnf_config_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, &unpack_pnf_phy_rf_config_value}, + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension); +} + + + static uint8_t unpack_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_config_request_t *pNfapiMsg = (nfapi_pnf_config_request_t*)msg; @@ -1160,6 +1626,20 @@ static uint8_t unpack_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension); } + +static uint8_t unpack_nr_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_config_response_t *pNfapiMsg = (nfapi_nr_pnf_config_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); + +} + static uint8_t unpack_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_config_response_t *pNfapiMsg = (nfapi_pnf_config_response_t*)msg; @@ -1173,6 +1653,18 @@ static uint8_t unpack_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *en } +static uint8_t unpack_nr_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_start_request_t *pNfapiMsg = (nfapi_nr_pnf_start_request_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); +} + + static uint8_t unpack_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_start_request_t *pNfapiMsg = (nfapi_pnf_start_request_t*)msg; @@ -1184,6 +1676,7 @@ static uint8_t unpack_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); } + static uint8_t unpack_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_start_response_t *pNfapiMsg = (nfapi_pnf_start_response_t*)msg; @@ -1196,6 +1689,19 @@ static uint8_t unpack_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); } +static uint8_t unpack_nr_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_pnf_start_response_t *pNfapiMsg = (nfapi_nr_pnf_start_response_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end ) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); +} + + static uint8_t unpack_pnf_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { nfapi_pnf_stop_request_t *pNfapiMsg = (nfapi_pnf_stop_request_t*)msg; @@ -1231,6 +1737,17 @@ static uint8_t unpack_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, voi return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); } +static uint8_t unpack_nr_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_param_request_scf_t *pNfapiMsg = (nfapi_nr_param_request_scf_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); +} + static uint8_t unpack_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t*)msg; @@ -1329,6 +1846,100 @@ static uint8_t unpack_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, vo } +static uint8_t unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_param_response_scf_t *pNfapiMsg = (nfapi_nr_param_response_scf_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->cell_param.release_capability), &unpack_uint16_tlv_value}, + { NFAPI_NR_PARAM_TLV_PHY_STATE_TAG, &(pNfapiMsg->cell_param.phy_state),&unpack_uint16_tlv_value}, + { NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_dl_config), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_ul_config), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG, &(pNfapiMsg->cell_param.num_config_tlvs_to_report ), &unpack_uint16_tlv_value}, + + { NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG, &(pNfapiMsg->carrier_param.cyclic_prefix), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_dl), &unpack_uint16_tlv_value}, + { NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_dl), &unpack_uint16_tlv_value}, + { NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_ul), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_ul), &unpack_uint16_tlv_value}, + + + { NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG, &(pNfapiMsg->pdcch_param.cce_mapping_type), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG, &(pNfapiMsg->pdcch_param.coreset_outside_first_3_of_ofdm_syms_of_slot), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG, &(pNfapiMsg->pdcch_param.coreset_precoder_granularity_coreset), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG, &(pNfapiMsg->pdcch_param.pdcch_mu_mimo), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG, &(pNfapiMsg->pdcch_param.pdcch_precoder_cycling), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG, &(pNfapiMsg->pdcch_param.max_pdcch_per_slot), &unpack_uint8_tlv_value}, + + { NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG, &(pNfapiMsg->pucch_param.pucch_formats), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG, &(pNfapiMsg->pucch_param.max_pucchs_per_slot), &unpack_uint8_tlv_value}, + + { NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pdsch_param.pdsch_mapping_type), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_allocation_types), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pdsch_param.pdsch_vrb_to_prb_mapping), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG, &(pNfapiMsg->pdsch_param.pdsch_cbg), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_config_types), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_max_length), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_additional_pos), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG, &(pNfapiMsg->pdsch_param.max_pdsch_tbs_per_slot), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG, &(pNfapiMsg->pdsch_param.max_number_mimo_layers_pdsch), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG, &(pNfapiMsg->pdsch_param.max_mu_mimo_users_dl), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG, &(pNfapiMsg->pdsch_param.pdsch_data_in_dmrs_symbols), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.premption_support), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.pdsch_non_slot_support), &unpack_uint8_tlv_value}, + + { NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_mux_ulsch_in_pusch), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_only_pusch), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG, &(pNfapiMsg->pusch_param.pusch_frequency_hopping), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_config_types), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_max_len), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_additional_pos), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG, &(pNfapiMsg->pusch_param.pusch_cbg), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pusch_param.pusch_mapping_type), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_allocation_types), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pusch_param.pusch_vrb_to_prb_mapping), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG, &(pNfapiMsg->pusch_param.pusch_max_ptrs_ports), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG, &(pNfapiMsg->pusch_param.max_pduschs_tbs_per_slot), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG, &(pNfapiMsg->pusch_param.max_number_mimo_layers_non_cb_pusch), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG, &(pNfapiMsg->pusch_param.supported_modulation_order_ul), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG, &(pNfapiMsg->pusch_param.max_mu_mimo_users_ul), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG, &(pNfapiMsg->pusch_param.dfts_ofdm_support), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG, &(pNfapiMsg->pusch_param.pusch_aggregation_factor), &unpack_uint8_tlv_value}, + + { NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_long_formats), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_short_formats), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG, &(pNfapiMsg->prach_param.prach_restricted_sets), &unpack_uint8_tlv_value}, + { NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG, &(pNfapiMsg->prach_param.max_prach_fd_occasions_in_a_slot), &unpack_uint8_tlv_value}, + + { NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG, &(pNfapiMsg->measurement_param.rssi_measurement_support), &unpack_uint8_tlv_value}, + //config + { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv4, &unpack_ipv4_address_value}, + { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv6, &unpack_ipv6_address_value}, + { NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_vnf_port, &unpack_uint16_tlv_value}, + { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv4, &unpack_ipv4_address_value}, + { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv6, &unpack_ipv6_address_value}, + { NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_pnf_port, &unpack_uint16_tlv_value}, + { NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &pNfapiMsg->nfapi_config.timing_window, &unpack_uint8_tlv_value}, + { NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value}, + { NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value}, + }; + // print ppReadPackedMsg + uint8_t *ptr = *ppReadPackedMsg; + printf("\n Read message unpack_param_response: "); + while(ptr < end){ + printf(" %d ", *ptr); + ptr++; + } + printf("\n"); + + + return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + +} + static uint8_t unpack_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { nfapi_config_request_t *pNfapiMsg = (nfapi_config_request_t*)msg; @@ -1454,6 +2065,66 @@ static uint8_t unpack_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, vo return ( pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) && unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} +static uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_config_request_scf_t *pNfapiMsg = (nfapi_nr_config_request_scf_t*)msg; + + pNfapiMsg->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t*) malloc(20*sizeof(nfapi_nr_max_tdd_periodicity_t)); + for(int i=0;i<40;i++) + pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list = (nfapi_nr_max_num_of_symbol_per_slot_t*) malloc(14*sizeof(nfapi_nr_max_num_of_symbol_per_slot_t)); + + pNfapiMsg->prach_config.num_prach_fd_occasions_list=(nfapi_nr_num_prach_fd_occasions_t *) malloc(sizeof(nfapi_nr_num_prach_fd_occasions_t)); + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.dl_bandwidth), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_DL_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.dl_frequency), &unpack_uint32_tlv_value}, + { NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.dl_grid_size[1]), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_DL_K0_TAG, &(pNfapiMsg->carrier_config.dl_k0[1]), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_NUM_RX_ANT_TAG, &(pNfapiMsg->carrier_config.num_rx_ant), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_NUM_TX_ANT_TAG, &(pNfapiMsg->carrier_config.num_tx_ant), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.ul_grid_size[1]), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_UL_K0_TAG, &(pNfapiMsg->carrier_config.ul_k0[1]), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.uplink_bandwidth), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.uplink_frequency), &unpack_uint32_tlv_value}, + { NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, &(pNfapiMsg->cell_config.frame_duplex_type), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_PHY_CELL_ID_TAG, &(pNfapiMsg->cell_config.phy_cell_id), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG, &(pNfapiMsg->prach_config.prach_sequence_length), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG, &(pNfapiMsg->prach_config.restricted_set_config), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_SSB_PER_RACH_TAG, &(pNfapiMsg->prach_config.ssb_per_rach), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG, &(pNfapiMsg->prach_config.prach_sub_c_spacing), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_root_sequence_index), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_K1_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].k1), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_zero_corr_conf), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].num_root_sequences), &unpack_uint8_tlv_value}, + + { NFAPI_NR_CONFIG_SCS_COMMON_TAG, &(pNfapiMsg->ssb_config.scs_common), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, &(pNfapiMsg->ssb_config.ss_pbch_power), &unpack_uint32_tlv_value}, + { NFAPI_NR_CONFIG_BETA_PSS_TAG, &(pNfapiMsg->ssb_table.beta_pss), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), &unpack_uint32_tlv_value}, + { NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask), &unpack_uint32_tlv_value}, + { NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[1].ssb_mask), &unpack_uint32_tlv_value}, + + { NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, &(pNfapiMsg->ssb_table.ssb_offset_point_a), &unpack_uint16_tlv_value}, + { NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG, &(pNfapiMsg->ssb_table.ssb_subcarrier_offset), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), &unpack_uint8_tlv_value}, + { NFAPI_NR_CONFIG_SLOT_CONFIG_TAG, &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[0].max_num_of_symbol_per_slot_list[0].slot_config), &unpack_uint8_tlv_value}, + { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), &unpack_ipv4_address_value}, + { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), &unpack_ipv6_address_value}, + { NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), &unpack_uint16_tlv_value}, + { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), &unpack_ipv4_address_value}, + { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), &unpack_ipv6_address_value}, + { NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), &unpack_uint16_tlv_value}, + { NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), &unpack_uint8_tlv_value}, + { NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), &unpack_uint8_tlv_value}, + { NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), &unpack_uint8_tlv_value}, + }; + return ( pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + } static uint8_t unpack_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) @@ -1468,9 +2139,32 @@ static uint8_t unpack_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, v unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); } +static uint8_t unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_config_response_scf_t *pNfapiMsg = (nfapi_nr_config_response_scf_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); +} + +static uint8_t unpack_nr_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_start_request_scf_t *pNfapiMsg = ( nfapi_nr_start_request_scf_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)); +} + static uint8_t unpack_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { - nfapi_start_request_t *pNfapiMsg = (nfapi_start_request_t*)msg; + nfapi_start_request_t *pNfapiMsg = ( nfapi_start_request_t*)msg; unpack_tlv_t unpack_fns[] = { @@ -1492,6 +2186,19 @@ static uint8_t unpack_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, vo } +static uint8_t unpack_nr_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_nr_start_response_scf_t *pNfapiMsg = (nfapi_nr_start_response_scf_t*)msg; + + unpack_tlv_t unpack_fns[] = + { + }; + + return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) && + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension))); + +} + static uint8_t unpack_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { nfapi_stop_request_t *pNfapiMsg = (nfapi_stop_request_t*)msg; @@ -1557,6 +2264,100 @@ static uint8_t unpack_measurement_response(uint8_t **ppReadPackedMsg, uint8_t *e // unpack length check +static int check_nr_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen) +{ + int retLen = 0; + + switch (msgId) + { + case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_pnf_param_request_t)) + retLen = sizeof(nfapi_pnf_param_request_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_nr_pnf_param_response_t)) + retLen = sizeof(nfapi_nr_pnf_param_response_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_nr_pnf_config_request_t)) + retLen = sizeof(nfapi_nr_pnf_config_request_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_nr_pnf_config_response_t)) + retLen = sizeof(nfapi_nr_pnf_config_response_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_nr_pnf_start_request_t)) + retLen = sizeof(nfapi_nr_pnf_start_request_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_nr_pnf_start_response_t)) + retLen = sizeof(nfapi_nr_pnf_start_response_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_nr_pnf_stop_request_t)) + retLen = sizeof(nfapi_nr_pnf_stop_request_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_nr_pnf_stop_response_t)) + retLen = sizeof(nfapi_nr_pnf_stop_response_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_nr_param_request_scf_t)) + retLen = sizeof(nfapi_nr_param_request_scf_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_nr_param_response_scf_t)) + retLen = sizeof(nfapi_nr_param_response_scf_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_nr_config_request_scf_t)) + retLen = sizeof(nfapi_nr_config_request_scf_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_nr_config_response_scf_t)) + retLen = sizeof(nfapi_nr_config_response_scf_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST: + if (unpackedBufLen >= sizeof( nfapi_nr_start_request_scf_t)) + retLen = sizeof( nfapi_nr_start_request_scf_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_nr_start_response_scf_t)) + retLen = sizeof(nfapi_nr_start_response_scf_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_stop_request_t)) + retLen = sizeof(nfapi_stop_request_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_stop_response_t)) + retLen = sizeof(nfapi_stop_response_t); + break; + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Unknown message ID %d\n", __FUNCTION__, msgId); + break; + } + + return retLen; +} + + static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) { int retLen = 0; @@ -1624,8 +2425,8 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen break; case NFAPI_START_REQUEST: - if (unpackedBufLen >= sizeof(nfapi_start_request_t)) - retLen = sizeof(nfapi_start_request_t); + if (unpackedBufLen >= sizeof( nfapi_start_request_t)) + retLen = sizeof( nfapi_start_request_t); break; case NFAPI_START_RESPONSE: @@ -1690,6 +2491,152 @@ int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo } +int nfapi_nr_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config) +{ + nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + if (pMessageBuf == NULL || pUnpackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied pointers are null\n"); + return -1; + } + + if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + return -1; + } + + uint8_t *ptr = pReadPackedMessage; + printf("\n Read message unpack: "); + while(ptr < end){ + printf(" %d ", *ptr); + ptr++; + } + printf("\n"); + + // clean the supplied buffer for - tag value blanking + (void)memset(pUnpackedBuf, 0, unpackedBufLen); + + // process the header + if( !(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end ) && + pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && + pull16(&pReadPackedMessage, &pMessageHeader->spare, end))) + { + // failed to read the header + return -1; + } + + int result = -1; + + + if(check_nr_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) + { + // the unpack buffer is not big enough for the struct + return -1; + } + + // look for the specific message + switch (pMessageHeader->message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST: + result = unpack_nr_pnf_param_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE: + result = unpack_nr_pnf_param_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST: + result = unpack_nr_pnf_config_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE: + result = unpack_nr_pnf_config_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST: + result = unpack_nr_pnf_start_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE: + result = unpack_nr_pnf_start_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST: + result = unpack_pnf_stop_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE: + result = unpack_pnf_stop_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST: + result = unpack_nr_param_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE: + result = unpack_nr_param_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST: + result = unpack_nr_config_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: + result = unpack_nr_config_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST: + result = unpack_nr_start_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE: + result = unpack_nr_start_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST: + result = unpack_stop_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE: + result = unpack_stop_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_MEASUREMENT_REQUEST: + result = unpack_measurement_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_MEASUREMENT_RESPONSE: + result = unpack_measurement_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + default: + if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->unpack_p4_p5_vendor_extension) + { + result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P5 message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + break; + } + + return result; +} + int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config) { nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf; @@ -1708,6 +2655,14 @@ int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn return -1; } + uint8_t *ptr = pReadPackedMessage; + printf("\n Read message unpack: "); + while(ptr < end){ + printf(" %d ", *ptr); + ptr++; + } + printf("\n"); + // clean the supplied buffer for - tag value blanking (void)memset(pUnpackedBuf, 0, unpackedBufLen); diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index be9205d035..ec59ba39b2 100755 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -1,1588 +1,2242 @@ -/* - * Copyright 2017 Cisco Systems, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -extern int nfapi_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t **ppReadPackedMsg, void* user_data); -extern int nfapi_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t **ppWritePackedMsg, void* user_data); - -uint32_t nfapi_calculate_checksum(uint8_t* buffer, uint16_t len) -{ - uint32_t chksum = 0; - // calcaulte upto the checksum - chksum = crc32(chksum, buffer, 8); - - // skip the checksum - uint8_t zeros[4] = {0, 0, 0, 0}; - chksum = crc32(chksum, zeros, 4); - - // continu with the rest of the mesage - chksum = crc32(chksum, &buffer[NFAPI_P7_HEADER_LENGTH], len - NFAPI_P7_HEADER_LENGTH); - - // return the inverse - return ~(chksum); -} - -int nfapi_p7_update_checksum(uint8_t* buffer, uint32_t len) -{ - uint32_t checksum = nfapi_calculate_checksum(buffer, len); - - uint8_t* p_write = &buffer[8]; - return (push32(checksum, &p_write, buffer + len) > 0 ? 0 : -1); -} - -int nfapi_p7_update_transmit_timestamp(uint8_t* buffer, uint32_t timestamp) -{ - uint8_t* p_write = &buffer[12]; - return (push32(timestamp, &p_write, buffer + 16) > 0 ? 0 : -1); -} - -uint32_t nfapi_p7_calculate_checksum(uint8_t* buffer, uint32_t len) -{ - return nfapi_calculate_checksum(buffer, len); -} - -void* nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t* config) -{ - if(size == 0) - return 0; - +/* + * Copyright 2017 Cisco Systems, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "nfapi_nr_interface_scf.h" + +extern int nfapi_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t **ppReadPackedMsg, void* user_data); +extern int nfapi_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t **ppWritePackedMsg, void* user_data); + +uint32_t nfapi_calculate_checksum(uint8_t* buffer, uint16_t len) +{ + uint32_t chksum = 0; + // calcaulte upto the checksum + chksum = crc32(chksum, buffer, 8); + + // skip the checksum + uint8_t zeros[4] = {0, 0, 0, 0}; + chksum = crc32(chksum, zeros, 4); + + // continu with the rest of the mesage + chksum = crc32(chksum, &buffer[NFAPI_P7_HEADER_LENGTH], len - NFAPI_P7_HEADER_LENGTH); + + // return the inverse + return ~(chksum); +} + +int nfapi_p7_update_checksum(uint8_t* buffer, uint32_t len) +{ + uint32_t checksum = nfapi_calculate_checksum(buffer, len); + + uint8_t* p_write = &buffer[8]; + return (push32(checksum, &p_write, buffer + len) > 0 ? 0 : -1); +} + +int nfapi_p7_update_transmit_timestamp(uint8_t* buffer, uint32_t timestamp) +{ + uint8_t* p_write = &buffer[12]; + return (push32(timestamp, &p_write, buffer + 16) > 0 ? 0 : -1); +} + +uint32_t nfapi_p7_calculate_checksum(uint8_t* buffer, uint32_t len) +{ + return nfapi_calculate_checksum(buffer, len); +} + +void* nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t* config) +{ + if(size == 0) + return 0; + void* buffer_p = NULL; - if(config && config->allocate) - { + if(config && config->allocate) + { buffer_p = (config->allocate)(size); if(buffer_p != NULL){ memset(buffer_p,0,size); } return buffer_p; - } - else - { + } + else + { buffer_p = calloc(1, size); return buffer_p; - } -} - -void nfapi_p7_deallocate(void* ptr, nfapi_p7_codec_config_t* config) -{ - if(ptr == NULL) - return; - - if(config && config->deallocate) - { - return (config->deallocate)(ptr); - } - else - { - return free(ptr); - } -} -// Pack routines - - -static uint8_t pack_dl_config_dci_dl_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel8_t* value = (nfapi_dl_config_dci_dl_pdu_rel8_t*)tlv; - - //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci_format:%u\n", __FUNCTION__, value->dci_format); - - return ( push8(value->dci_format, ppWritePackedMsg, end) && - push8(value->cce_idx, ppWritePackedMsg, end) && - push8(value->aggregation_level, ppWritePackedMsg, end) && - push16(value->rnti, ppWritePackedMsg, end) && - push8(value->resource_allocation_type, ppWritePackedMsg, end) && - push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) && - push32(value->resource_block_coding, ppWritePackedMsg, end) && - push8(value->mcs_1, ppWritePackedMsg, end) && - push8(value->redundancy_version_1, ppWritePackedMsg, end) && - push8(value->new_data_indicator_1, ppWritePackedMsg, end) && - push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) && - push8(value->mcs_2, ppWritePackedMsg, end) && - push8(value->redundancy_version_2, ppWritePackedMsg, end) && - push8(value->new_data_indicator_2, ppWritePackedMsg, end) && - push8(value->harq_process, ppWritePackedMsg, end) && - push8(value->tpmi, ppWritePackedMsg, end) && - push8(value->pmi, ppWritePackedMsg, end) && - push8(value->precoding_information, ppWritePackedMsg, end) && - push8(value->tpc, ppWritePackedMsg, end) && - push8(value->downlink_assignment_index, ppWritePackedMsg, end) && - push8(value->ngap, ppWritePackedMsg, end) && - push8(value->transport_block_size_index, ppWritePackedMsg, end) && - push8(value->downlink_power_offset, ppWritePackedMsg, end) && - push8(value->allocate_prach_flag, ppWritePackedMsg, end) && - push8(value->preamble_index, ppWritePackedMsg, end) && - push8(value->prach_mask_index, ppWritePackedMsg, end) && - push8(value->rnti_type, ppWritePackedMsg, end) && - push16(value->transmission_power, ppWritePackedMsg, end)); -} - -static uint8_t pack_dl_config_dci_dl_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel9_t* value = (nfapi_dl_config_dci_dl_pdu_rel9_t*)tlv; - - return( push8(value->mcch_flag, ppWritePackedMsg, end) && - push8(value->mcch_change_notification, ppWritePackedMsg, end) && - push8(value->scrambling_identity, ppWritePackedMsg, end)); -} - -static uint8_t pack_dl_config_dci_dl_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel10_t* value = (nfapi_dl_config_dci_dl_pdu_rel10_t*)tlv; - - return ( push8(value->cross_carrier_scheduling_flag, ppWritePackedMsg, end) && - push8(value->carrier_indicator, ppWritePackedMsg, end) && - push8(value->srs_flag, ppWritePackedMsg, end) && - push8(value->srs_request, ppWritePackedMsg, end) && - push8(value->antenna_ports_scrambling_and_layers, ppWritePackedMsg, end) && - push8(value->total_dci_length_including_padding, ppWritePackedMsg, end) && - push8(value->n_dl_rb, ppWritePackedMsg, end)); -} - -static uint8_t pack_dl_config_dci_dl_pdu_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel11_t* value = (nfapi_dl_config_dci_dl_pdu_rel11_t*)tlv; - - return ( push8(value->harq_ack_resource_offset, ppWritePackedMsg, end) && - push8(value->pdsch_re_mapping_quasi_co_location_indicator, ppWritePackedMsg, end)); -} - -static uint8_t pack_dl_config_dci_dl_pdu_rel12_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel12_t* value = (nfapi_dl_config_dci_dl_pdu_rel12_t*)tlv; - - return ( push8(value->primary_cell_type, ppWritePackedMsg, end) && - push8(value->ul_dl_configuration_flag, ppWritePackedMsg, end) && - push8(value->number_ul_dl_configurations, ppWritePackedMsg, end) && - pusharray8(value->ul_dl_configuration_indication, NFAPI_MAX_UL_DL_CONFIGURATIONS, value->number_ul_dl_configurations, ppWritePackedMsg, end)); -} - -static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t* value, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - if (!( push8(value->num_prb_per_subband, ppWritePackedMsg, end) && - push8(value->number_of_subbands, ppWritePackedMsg, end) && - push8(value->num_antennas, ppWritePackedMsg, end))) - return 0; - - uint8_t idx = 0; - for(idx = 0; idx < value->number_of_subbands; ++idx) - { - nfapi_dl_config_dci_dl_tpm_subband_info_t* subband_info = &(value->subband_info[idx]); - - if(!(push8(subband_info->subband_index, ppWritePackedMsg, end) && - push8(subband_info->scheduled_ues, ppWritePackedMsg, end))) - return 0; - - - uint8_t antenna_idx = 0; - uint8_t scheduled_ue_idx = 0; - - for(antenna_idx = 0; antenna_idx < value->num_antennas; ++antenna_idx) - { - for(scheduled_ue_idx = 0; scheduled_ue_idx < subband_info->scheduled_ues; ++scheduled_ue_idx) - { - if(!push16(subband_info->precoding_value[antenna_idx][scheduled_ue_idx], ppWritePackedMsg, end)) - return 0; - } - } - - } - - - return 1; - -} - -static uint8_t pack_dl_config_dci_dl_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel13_t* value = (nfapi_dl_config_dci_dl_pdu_rel13_t*)tlv; - - return( push8(value->laa_end_partial_sf_flag, ppWritePackedMsg, end) && - push8(value->laa_end_partial_sf_configuration, ppWritePackedMsg, end) && - push8(value->initial_lbt_sf, ppWritePackedMsg, end) && - push8(value->codebook_size_determination, ppWritePackedMsg, end) && - push8(value->drms_table_flag, ppWritePackedMsg, end) && - push8(value->tpm_struct_flag, ppWritePackedMsg, end) && - (value->tpm_struct_flag == 1 ? pack_tpm_value(&(value->tpm), ppWritePackedMsg, end) : 1)); -} - -static uint8_t pack_dl_config_bch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_bch_pdu_rel8_t* value = (nfapi_dl_config_bch_pdu_rel8_t*)tlv; - - //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s()\n", __FUNCTION__); - - return( push16(value->length, ppWritePackedMsg, end) && - push16(value->pdu_index, ppWritePackedMsg, end) && - push16(value->transmission_power, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_mch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_mch_pdu_rel8_t* value = (nfapi_dl_config_mch_pdu_rel8_t*)tlv; - - return ( push16(value->length, ppWritePackedMsg, end) && - push16(value->pdu_index, ppWritePackedMsg, end) && - push16(value->rnti, ppWritePackedMsg, end) && - push8(value->resource_allocation_type, ppWritePackedMsg, end) && - push32(value->resource_block_coding, ppWritePackedMsg, end) && - push8(value->modulation, ppWritePackedMsg, end) && - push16(value->transmission_power, ppWritePackedMsg, end) && - push16(value->mbsfn_area_id, ppWritePackedMsg, end)); -} - -static uint8_t pack_bf_vector_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_bf_vector_t* bf = (nfapi_bf_vector_t*)elem; - - return ( push8(bf->subband_index, ppWritePackedMsg, end) && - push8(bf->num_antennas, ppWritePackedMsg, end) && - pusharray16(bf->bf_value, NFAPI_MAX_NUM_ANTENNAS, bf->num_antennas, ppWritePackedMsg, end)); - - -} -static uint8_t pack_dl_config_dlsch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel8_t* value = (nfapi_dl_config_dlsch_pdu_rel8_t*)tlv; - - return ( push16(value->length, ppWritePackedMsg, end) && - push16(value->pdu_index, ppWritePackedMsg, end) && - push16(value->rnti, ppWritePackedMsg, end) && - push8(value->resource_allocation_type, ppWritePackedMsg, end) && - push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) && - push32(value->resource_block_coding, ppWritePackedMsg, end) && - push8(value->modulation, ppWritePackedMsg, end) && - push8(value->redundancy_version, ppWritePackedMsg, end) && - push8(value->transport_blocks, ppWritePackedMsg, end) && - push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) && - push8(value->transmission_scheme, ppWritePackedMsg, end) && - push8(value->number_of_layers, ppWritePackedMsg, end) && - push8(value->number_of_subbands, ppWritePackedMsg, end) && - pusharray8(value->codebook_index, NFAPI_MAX_NUM_SUBBANDS, value->number_of_subbands, ppWritePackedMsg, end) && - push8(value->ue_category_capacity, ppWritePackedMsg, end) && - push8(value->pa, ppWritePackedMsg, end) && - push8(value->delta_power_offset_index, ppWritePackedMsg, end) && - push8(value->ngap, ppWritePackedMsg, end) && - push8(value->nprb, ppWritePackedMsg, end) && - push8(value->transmission_mode, ppWritePackedMsg, end) && - push8(value->num_bf_prb_per_subband, ppWritePackedMsg, end) && - push8(value->num_bf_vector, ppWritePackedMsg, end) && - packarray(value->bf_vector, sizeof(nfapi_bf_vector_t), NFAPI_MAX_BF_VECTORS, value->num_bf_vector, ppWritePackedMsg, end, &pack_bf_vector_info)); - -} -static uint8_t pack_dl_config_dlsch_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel9_t* value = (nfapi_dl_config_dlsch_pdu_rel9_t*)tlv; - return ( push8(value->nscid, ppWritePackedMsg, end) ); -} -static uint8_t pack_dl_config_dlsch_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel10_t* value = (nfapi_dl_config_dlsch_pdu_rel10_t*)tlv; - - return ( push8(value->csi_rs_flag, ppWritePackedMsg, end) && - push8(value->csi_rs_resource_config_r10, ppWritePackedMsg, end) && - push16(value->csi_rs_zero_tx_power_resource_config_bitmap_r10, ppWritePackedMsg, end) && - push8(value->csi_rs_number_nzp_configuration, ppWritePackedMsg, end) && - pusharray8(value->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, value->csi_rs_number_nzp_configuration, ppWritePackedMsg, end) && - push8(value->pdsch_start, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_dlsch_pdu_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel11_t* value = (nfapi_dl_config_dlsch_pdu_rel11_t*)tlv; - - return( push8(value->drms_config_flag, ppWritePackedMsg, end) && - push16(value->drms_scrambling, ppWritePackedMsg, end) && - push8(value->csi_config_flag, ppWritePackedMsg, end) && - push16(value->csi_scrambling, ppWritePackedMsg, end) && - push8(value->pdsch_re_mapping_flag, ppWritePackedMsg, end) && - push8(value->pdsch_re_mapping_atenna_ports, ppWritePackedMsg, end) && - push8(value->pdsch_re_mapping_freq_shift, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_dlsch_pdu_rel12_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel12_t* value = (nfapi_dl_config_dlsch_pdu_rel12_t*)tlv; - - return( push8(value->altcqi_table_r12, ppWritePackedMsg, end) && - push8(value->maxlayers, ppWritePackedMsg, end) && - push8(value->n_dl_harq, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_dlsch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel13_t* value = (nfapi_dl_config_dlsch_pdu_rel13_t*)tlv; - - return( push8(value->dwpts_symbols, ppWritePackedMsg, end) && - push8(value->initial_lbt_sf, ppWritePackedMsg, end) && - push8(value->ue_type, ppWritePackedMsg, end) && - push8(value->pdsch_payload_type, ppWritePackedMsg, end) && - push16(value->initial_transmission_sf_io, ppWritePackedMsg, end) && - push8(value->drms_table_flag, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_pch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_pch_pdu_rel8_t* value = (nfapi_dl_config_pch_pdu_rel8_t*)tlv; - - return( push16(value->length, ppWritePackedMsg, end) && - push16(value->pdu_index, ppWritePackedMsg, end) && - push16(value->p_rnti, ppWritePackedMsg, end) && - push8(value->resource_allocation_type, ppWritePackedMsg, end) && - push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) && - push32(value->resource_block_coding, ppWritePackedMsg, end) && - push8(value->mcs, ppWritePackedMsg, end) && - push8(value->redundancy_version, ppWritePackedMsg, end) && - push8(value->number_of_transport_blocks, ppWritePackedMsg, end) && - push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) && - push8(value->transmission_scheme, ppWritePackedMsg, end) && - push8(value->number_of_layers, ppWritePackedMsg, end) && - push8(value->codebook_index, ppWritePackedMsg, end) && - push8(value->ue_category_capacity, ppWritePackedMsg, end) && - push8(value->pa, ppWritePackedMsg, end) && - push16(value->transmission_power, ppWritePackedMsg, end) && - push8(value->nprb, ppWritePackedMsg, end) && - push8(value->ngap, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_pch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_pch_pdu_rel13_t* value = (nfapi_dl_config_pch_pdu_rel13_t*)tlv; - - return ( push8(value->ue_mode, ppWritePackedMsg, end) && - push16(value->initial_transmission_sf_io, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_prs_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_prs_pdu_rel9_t* value = (nfapi_dl_config_prs_pdu_rel9_t*)tlv; - - return( push16(value->transmission_power, ppWritePackedMsg, end) && - push8(value->prs_bandwidth, ppWritePackedMsg, end) && - push8(value->prs_cyclic_prefix_type, ppWritePackedMsg, end) && - push8(value->prs_muting, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_csi_rs_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_csi_rs_pdu_rel10_t* value = (nfapi_dl_config_csi_rs_pdu_rel10_t*)tlv; - - return( push8(value->csi_rs_antenna_port_count_r10, ppWritePackedMsg, end) && - push8(value->csi_rs_resource_config_r10, ppWritePackedMsg, end) && - push16(value->transmission_power, ppWritePackedMsg, end) && - push16(value->csi_rs_zero_tx_power_resource_config_bitmap_r10, ppWritePackedMsg, end) && - push8(value->csi_rs_number_of_nzp_configuration, ppWritePackedMsg, end) && - pusharray8(value->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, value->csi_rs_number_of_nzp_configuration, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_csi_rs_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_csi_rs_pdu_rel13_t* value = (nfapi_dl_config_csi_rs_pdu_rel13_t*)tlv; - - if(!(push8(value->csi_rs_class, ppWritePackedMsg, end) && - push8(value->cdm_type, ppWritePackedMsg, end) && - push8(value->num_bf_vector, ppWritePackedMsg, end))) - { - return 0; - } - - uint16_t i; - for(i = 0; i < value->num_bf_vector; ++i) - { - if(!(push8(value->bf_vector[i].csi_rs_resource_index, ppWritePackedMsg, end) && - pusharray16(value->bf_vector[i].bf_value, NFAPI_MAX_ANTENNA_PORT_COUNT, NFAPI_MAX_ANTENNA_PORT_COUNT, ppWritePackedMsg, end))) - return 0; - } - - return 1; -} -static uint8_t pack_bf_vector(nfapi_bf_vector_t* vector, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( push8(vector->subband_index, ppWritePackedMsg, end) && - push8(vector->num_antennas, ppWritePackedMsg, end) && - pusharray16(vector->bf_value, NFAPI_MAX_NUM_ANTENNAS, vector->num_antennas, ppWritePackedMsg, end)); -} - -static uint8_t pack_dl_config_epdcch_parameters_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_epdcch_parameters_rel11_t* value = (nfapi_dl_config_epdcch_parameters_rel11_t*)tlv; - - return ( push8(value->epdcch_resource_assignment_flag, ppWritePackedMsg, end) && - push16(value->epdcch_id, ppWritePackedMsg, end) && - push8(value->epdcch_start_symbol, ppWritePackedMsg, end) && - push8(value->epdcch_num_prb, ppWritePackedMsg, end) && - pusharray8(value->epdcch_prb_index, NFAPI_MAX_EPDCCH_PRB, value->epdcch_num_prb, ppWritePackedMsg, end) && - pack_bf_vector(&value->bf_vector, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_epdcch_parameters_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_epdcch_parameters_rel13_t* value = (nfapi_dl_config_epdcch_parameters_rel13_t*)tlv; - - return (push8(value->dwpts_symbols, ppWritePackedMsg, end) && - push8(value->initial_lbt_sf, ppWritePackedMsg, end)); -} -static uint8_t pack_dl_config_mpdcch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_mpdcch_pdu_rel13_t* value = (nfapi_dl_config_mpdcch_pdu_rel13_t*)tlv; - - return ( push8(value->mpdcch_narrow_band, ppWritePackedMsg, end) && - push8(value->number_of_prb_pairs, ppWritePackedMsg, end) && - push8(value->resource_block_assignment, ppWritePackedMsg, end) && - push8(value->mpdcch_tansmission_type, ppWritePackedMsg, end) && - push8(value->start_symbol, ppWritePackedMsg, end) && - push8(value->ecce_index, ppWritePackedMsg, end) && - push8(value->aggregation_level, ppWritePackedMsg, end) && - push8(value->rnti_type, ppWritePackedMsg, end) && - push16(value->rnti, ppWritePackedMsg, end) && - push8(value->ce_mode, ppWritePackedMsg, end) && - push16(value->drms_scrambling_init, ppWritePackedMsg, end) && - push16(value->initial_transmission_sf_io, ppWritePackedMsg, end) && - push16(value->transmission_power, ppWritePackedMsg, end) && - push8(value->dci_format, ppWritePackedMsg, end) && - push16(value->resource_block_coding, ppWritePackedMsg, end) && - push8(value->mcs, ppWritePackedMsg, end) && - push8(value->pdsch_reptition_levels, ppWritePackedMsg, end) && - push8(value->redundancy_version, ppWritePackedMsg, end) && - push8(value->new_data_indicator, ppWritePackedMsg, end) && - push8(value->harq_process, ppWritePackedMsg, end) && - push8(value->tpmi_length, ppWritePackedMsg, end) && - push8(value->tpmi, ppWritePackedMsg, end) && - push8(value->pmi_flag, ppWritePackedMsg, end) && - push8(value->pmi, ppWritePackedMsg, end) && - push8(value->harq_resource_offset, ppWritePackedMsg, end) && - push8(value->dci_subframe_repetition_number, ppWritePackedMsg, end) && - push8(value->tpc, ppWritePackedMsg, end) && - push8(value->downlink_assignment_index_length, ppWritePackedMsg, end) && - push8(value->downlink_assignment_index, ppWritePackedMsg, end) && - push8(value->allocate_prach_flag, ppWritePackedMsg, end) && - push8(value->preamble_index, ppWritePackedMsg, end) && - push8(value->prach_mask_index, ppWritePackedMsg, end) && - push8(value->starting_ce_level, ppWritePackedMsg, end) && - push8(value->srs_request, ppWritePackedMsg, end) && - push8(value->antenna_ports_and_scrambling_identity_flag, ppWritePackedMsg, end) && - push8(value->antenna_ports_and_scrambling_identity, ppWritePackedMsg, end) && - push8(value->frequency_hopping_enabled_flag, ppWritePackedMsg, end) && - push8(value->paging_direct_indication_differentiation_flag, ppWritePackedMsg, end) && - push8(value->direct_indication, ppWritePackedMsg, end) && - push8(value->total_dci_length_including_padding, ppWritePackedMsg, end) && - push8(value->number_of_tx_antenna_ports, ppWritePackedMsg, end) && - pusharray16(value->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, value->number_of_tx_antenna_ports, ppWritePackedMsg, end)); -} - - -static uint8_t pack_dl_config_nbch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_nbch_pdu_rel13_t* value = (nfapi_dl_config_nbch_pdu_rel13_t*)tlv; - - return (push16(value->length, ppWritePackedMsg, end) && - push16(value->pdu_index, ppWritePackedMsg, end) && - push16(value->transmission_power, ppWritePackedMsg, end) && - push16(value->hyper_sfn_2_lsbs, ppWritePackedMsg, end)); -} - - -static uint8_t pack_dl_config_npdcch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_npdcch_pdu_rel13_t* value = (nfapi_dl_config_npdcch_pdu_rel13_t*)tlv; - - return (push16(value->length, ppWritePackedMsg, end) && - push16(value->pdu_index, ppWritePackedMsg, end) && - push8(value->ncce_index, ppWritePackedMsg, end) && - push8(value->aggregation_level, ppWritePackedMsg, end) && - push8(value->start_symbol, ppWritePackedMsg, end) && - push8(value->rnti_type, ppWritePackedMsg, end) && - push16(value->rnti, ppWritePackedMsg, end) && - push8(value->scrambling_reinitialization_batch_index, ppWritePackedMsg, end) && - push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end) && - push8(value->dci_format, ppWritePackedMsg, end) && - push8(value->scheduling_delay, ppWritePackedMsg, end) && - push8(value->resource_assignment, ppWritePackedMsg, end) && - push8(value->repetition_number, ppWritePackedMsg, end) && - push8(value->mcs, ppWritePackedMsg, end) && - push8(value->new_data_indicator, ppWritePackedMsg, end) && - push8(value->harq_ack_resource, ppWritePackedMsg, end) && - push8(value->npdcch_order_indication, ppWritePackedMsg, end) && - push8(value->starting_number_of_nprach_repetitions, ppWritePackedMsg, end) && - push8(value->subcarrier_indication_of_nprach, ppWritePackedMsg, end) && - push8(value->paging_direct_indication_differentation_flag, ppWritePackedMsg, end) && - push8(value->direct_indication, ppWritePackedMsg, end) && - push8(value->dci_subframe_repetition_number, ppWritePackedMsg, end) && - push8(value->total_dci_length_including_padding, ppWritePackedMsg, end)); -} - -static uint8_t pack_dl_config_ndlsch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_ndlsch_pdu_rel13_t* value = (nfapi_dl_config_ndlsch_pdu_rel13_t*)tlv; - - return (push16(value->length, ppWritePackedMsg, end) && - push16(value->pdu_index, ppWritePackedMsg, end) && - push8(value->start_symbol, ppWritePackedMsg, end) && - push8(value->rnti_type, ppWritePackedMsg, end) && - push16(value->rnti, ppWritePackedMsg, end) && - push16(value->resource_assignment, ppWritePackedMsg, end) && - push16(value->repetition_number, ppWritePackedMsg, end) && - push8(value->modulation, ppWritePackedMsg, end) && - push8(value->number_of_subframes_for_resource_assignment, ppWritePackedMsg, end) && - push8(value->scrambling_sequence_initialization_cinit, ppWritePackedMsg, end) && - push16(value->sf_idx, ppWritePackedMsg, end) && - push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end)); -} - -static uint8_t pack_dl_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv; - - //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci:%u pdu:%u pdsch:%u rnti:%u pcfich:%u\n", __FUNCTION__, value->number_dci, value->number_pdu, value->number_pdsch_rnti, value->transmission_power_pcfich); - - if(!(push8(value->number_pdcch_ofdm_symbols, ppWritePackedMsg, end) && - push8(value->number_dci, ppWritePackedMsg, end) && - push16(value->number_pdu, ppWritePackedMsg, end) && - push8(value->number_pdsch_rnti, ppWritePackedMsg, end) && - push16(value->transmission_power_pcfich, ppWritePackedMsg, end))) - { - return 0; - } - - uint16_t i = 0; - uint16_t total_number_of_pdus = value->number_pdu; - for(; i < total_number_of_pdus; ++i) - { - nfapi_dl_config_request_pdu_t* pdu = &(value->dl_config_pdu_list[i]); - - if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) - return 0; - - // Put a 0 size in and then determine the size after the pdu - // has been writen and write the calculated size - uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; - pdu->pdu_size = 0; - if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) - return 0; - - switch(pdu->pdu_type) - { - case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: - { - //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE\n", __FUNCTION__); - - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel11_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel12_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel13_value))) - { - return 0; - } - } - break; - case NFAPI_DL_CONFIG_BCH_PDU_TYPE: - { - //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE\n", __FUNCTION__); - - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_bch_pdu_rel8_value))) - return 0; - } - break; - case NFAPI_DL_CONFIG_MCH_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG, &pdu->mch_pdu.mch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_mch_pdu_rel8_value))) - return 0; - } - break; - case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel8_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel9_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel10_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel11_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel12_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel13_value))) - return 0; - } - break; - case NFAPI_DL_CONFIG_PCH_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG, &pdu->pch_pdu.pch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_pch_pdu_rel8_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG, &pdu->pch_pdu.pch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_pch_pdu_rel13_value))) - return 0; - } - break; - case NFAPI_DL_CONFIG_PRS_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG, &pdu->prs_pdu.prs_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_prs_pdu_rel9_value))) - return 0; - } - break; - case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_csi_rs_pdu_rel10_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_csi_rs_pdu_rel13_value))) - return 0; - } - break; - case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel11_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel12_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel13_value) && - pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG, &pdu->epdcch_pdu.epdcch_params_rel11, ppWritePackedMsg, end, &pack_dl_config_epdcch_parameters_rel11_value) & - pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG, &pdu->epdcch_pdu.epdcch_params_rel13, ppWritePackedMsg, end, &pack_dl_config_epdcch_parameters_rel13_value))) - return 0; - } - break; - case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG, &pdu->mpdcch_pdu.mpdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_mpdcch_pdu_rel13_value))) - return 0; - } - break; - case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG, &pdu->nbch_pdu.nbch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_nbch_pdu_rel13_value))) - return 0; - } - break; - case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG, &pdu->npdcch_pdu.npdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_npdcch_pdu_rel13_value))) - return 0; - } - break; - case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG, &pdu->ndlsch_pdu.ndlsch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_ndlsch_pdu_rel13_value))) - return 0; - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); - } - break; - }; - - // add 1 for the pdu_type. The delta will include the pdu_size - pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); - push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); - } - - return 1; -} - -static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t*)msg; - - //return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - //pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value) && - //pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); - { - uint8_t x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); - uint8_t y = pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value); - uint8_t z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); - - if (!x || !y || !z) - { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST x:%u y:%u z:%u \n", __FUNCTION__,x,y,z); - } - - return x && y && z; - } -} - -static uint8_t pack_ul_config_request_ulsch_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t * end) -{ - nfapi_ul_config_ulsch_pdu_rel8_t* ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t*)tlv; - - return( push32(ulsch_pdu_rel8->handle, ppWritePackedMsg, end) && - push16(ulsch_pdu_rel8->size, ppWritePackedMsg, end) && - push16(ulsch_pdu_rel8->rnti, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->resource_block_start, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->modulation_type, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->frequency_hopping_enabled_flag, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->frequency_hopping_bits, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->new_data_indication, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->redundancy_version, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->harq_process_number, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->ul_tx_mode, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->current_tx_nb, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel8->n_srs, ppWritePackedMsg, end)); -} -static uint8_t pack_ul_config_request_ulsch_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_pdu_rel10_t* ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t*)tlv; - - return (push8(ulsch_pdu_rel10->resource_allocation_type, ppWritePackedMsg, end) && - push32(ulsch_pdu_rel10->resource_block_coding, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel10->transport_blocks, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel10->transmission_scheme, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel10->number_of_layers, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel10->codebook_index, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel10->disable_sequence_hopping_flag, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_ulsch_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_pdu_rel11_t* ulsch_pdu_rel11 = (nfapi_ul_config_ulsch_pdu_rel11_t*)tlv; - - return (push8(ulsch_pdu_rel11->virtual_cell_id_enabled_flag, ppWritePackedMsg, end) && - push16(ulsch_pdu_rel11->npusch_identity, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel11->dmrs_config_flag, ppWritePackedMsg, end) && - push16(ulsch_pdu_rel11->ndmrs_csh_identity, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_ulsch_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_pdu_rel13_t* ulsch_pdu_rel13 = (nfapi_ul_config_ulsch_pdu_rel13_t*)tlv; - - return (push8(ulsch_pdu_rel13->ue_type, ppWritePackedMsg, end) && - push16(ulsch_pdu_rel13->total_number_of_repetitions, ppWritePackedMsg, end) && - push16(ulsch_pdu_rel13->repetition_number, ppWritePackedMsg, end) && - push16(ulsch_pdu_rel13->initial_transmission_sf_io, ppWritePackedMsg, end) && - push8(ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu* ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &ulsch_pdu->ulsch_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel8_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &ulsch_pdu->ulsch_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel10_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG, &ulsch_pdu->ulsch_pdu_rel11, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel11_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG, &ulsch_pdu->ulsch_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel13_value)); -} - -static uint8_t pack_ul_config_request_cqi_ri_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_ri_information_rel8_t* cqi_ri_info_rel8 = (nfapi_ul_config_cqi_ri_information_rel8_t*)tlv; - - return ( push8(cqi_ri_info_rel8->dl_cqi_pmi_size_rank_1, ppWritePackedMsg, end) && - push8(cqi_ri_info_rel8->dl_cqi_pmi_size_rank_greater_1, ppWritePackedMsg, end) && - push8(cqi_ri_info_rel8->ri_size, ppWritePackedMsg, end) && - push8(cqi_ri_info_rel8->delta_offset_cqi, ppWritePackedMsg, end) && - push8(cqi_ri_info_rel8->delta_offset_ri, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_cqi_ri_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_ri_information_rel9_t* cqi_ri_info_rel9 = (nfapi_ul_config_cqi_ri_information_rel9_t*)tlv; - - if(!(push8(cqi_ri_info_rel9->report_type, ppWritePackedMsg, end) && - push8(cqi_ri_info_rel9->delta_offset_cqi, ppWritePackedMsg, end) && - push8(cqi_ri_info_rel9->delta_offset_ri, ppWritePackedMsg, end))) - { - return 0; - } - - switch(cqi_ri_info_rel9->report_type) - { - case NFAPI_CSI_REPORT_TYPE_PERIODIC: - { - if(!(push8(cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size, ppWritePackedMsg, end) && - push8(cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.control_type, ppWritePackedMsg, end))) - { - return 0; - } - } - break; - case NFAPI_CSI_REPORT_TYPE_APERIODIC: - { - if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc, ppWritePackedMsg, end) == 0) - return 0; - - uint8_t i; - for(i = 0; i < cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc; ++i) - { - if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, ppWritePackedMsg, end) == 0) - return 0; - - uint8_t j; - for(j = 0; j < 8; ++j) - { - if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], ppWritePackedMsg, end) == 0) - return 0; - } - } - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel9->report_type ); - } - break; - }; - - return 1; -} - -static uint8_t pack_ul_config_request_cqi_ri_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_ri_information_rel13_t* cqi_ri_info_rel13 = (nfapi_ul_config_cqi_ri_information_rel13_t*)tlv; - - switch(cqi_ri_info_rel13->report_type) - { - case NFAPI_CSI_REPORT_TYPE_PERIODIC: - { - if(push16(cqi_ri_info_rel13->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2, ppWritePackedMsg, end) == 0) - return 0; - } - break; - case NFAPI_CSI_REPORT_TYPE_APERIODIC: - { - // No parameters - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel13->report_type ); - } - break; - }; - - return 1; -} - -static uint8_t pack_ul_config_request_cqi_ri_information(nfapi_ul_config_cqi_ri_information* cqi_ri_info, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return (pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG, &cqi_ri_info->cqi_ri_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel8_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG, &cqi_ri_info->cqi_ri_information_rel9, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel9_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG, &cqi_ri_info->cqi_ri_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel13_value)); - -} - -static uint8_t pack_ul_config_request_init_tx_params_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_initial_transmission_parameters_rel8_t* init_tx_params_rel8 = (nfapi_ul_config_initial_transmission_parameters_rel8_t*)tlv; - - return (push8(init_tx_params_rel8->n_srs_initial, ppWritePackedMsg, end) && - push8(init_tx_params_rel8->initial_number_of_resource_blocks, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_initial_transmission_parameters(nfapi_ul_config_initial_transmission_parameters* init_tx_params, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return pack_tlv(NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG, &init_tx_params->initial_transmission_parameters_rel8, ppWritePackedMsg, end, &pack_ul_config_request_init_tx_params_rel8_value); -} - -static uint8_t pack_ul_config_request_ulsch_harq_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_harq_information_rel10_t* harq_info_rel10 = (nfapi_ul_config_ulsch_harq_information_rel10_t*)tlv; - - return (push8(harq_info_rel10->harq_size, ppWritePackedMsg, end) && - push8(harq_info_rel10->delta_offset_harq, ppWritePackedMsg, end) && - push8(harq_info_rel10->ack_nack_mode, ppWritePackedMsg, end)); -} -static uint8_t pack_ul_config_request_ulsch_harq_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_ulsch_harq_information_rel13_t*)tlv; - - return (push16(harq_info_rel13->harq_size_2, ppWritePackedMsg, end) && - push8(harq_info_rel13->delta_offset_harq_2, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_ulsch_harq_information(nfapi_ul_config_ulsch_harq_information* harq_info, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG, &harq_info->harq_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_harq_info_rel10_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG, &harq_info->harq_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_harq_info_rel13_value)); -} - -static uint8_t pack_ul_config_request_ue_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_ue_information_rel8_t* ue_info_rel8 = (nfapi_ul_config_ue_information_rel8_t*)tlv; - - return ( push32(ue_info_rel8->handle, ppWritePackedMsg, end) && - push16(ue_info_rel8->rnti, ppWritePackedMsg, end)); -} -static uint8_t pack_ul_config_request_ue_info_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_ue_information_rel11_t* ue_info_rel11 = (nfapi_ul_config_ue_information_rel11_t*)tlv; - - return ( push8(ue_info_rel11->virtual_cell_id_enabled_flag, ppWritePackedMsg, end) && - push16(ue_info_rel11->npusch_identity, ppWritePackedMsg, end)); -} -static uint8_t pack_ul_config_request_ue_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_ue_information_rel13_t* ue_info_rel13 = (nfapi_ul_config_ue_information_rel13_t*)tlv; - - return ( push8(ue_info_rel13->ue_type, ppWritePackedMsg, end) && - push8(ue_info_rel13->empty_symbols, ppWritePackedMsg, end) && - push16(ue_info_rel13->total_number_of_repetitions, ppWritePackedMsg, end) && - push16(ue_info_rel13->repetition_number, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_ue_information(nfapi_ul_config_ue_information* ue_info, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &ue_info->ue_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel8_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &ue_info->ue_information_rel11, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel11_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &ue_info->ue_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel13_value)); -} - -static uint8_t pack_ul_config_request_harq_info_rel10_tdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_harq_information_rel10_tdd_t* harq_info_rel10_tdd = (nfapi_ul_config_harq_information_rel10_tdd_t*)tlv; - - return ( push8(harq_info_rel10_tdd->harq_size, ppWritePackedMsg, end) && - push8(harq_info_rel10_tdd->ack_nack_mode, ppWritePackedMsg, end) && - push8(harq_info_rel10_tdd->number_of_pucch_resources, ppWritePackedMsg, end) && - push16(harq_info_rel10_tdd->n_pucch_1_0, ppWritePackedMsg, end) && - push16(harq_info_rel10_tdd->n_pucch_1_1, ppWritePackedMsg, end) && - push16(harq_info_rel10_tdd->n_pucch_1_2, ppWritePackedMsg, end) && - push16(harq_info_rel10_tdd->n_pucch_1_3, ppWritePackedMsg, end)); -} -static uint8_t pack_ul_config_request_harq_info_rel8_fdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_harq_information_rel8_fdd_t* harq_info_rel8_fdd = (nfapi_ul_config_harq_information_rel8_fdd_t*)tlv; - - return ( push16(harq_info_rel8_fdd->n_pucch_1_0, ppWritePackedMsg, end) && - push8(harq_info_rel8_fdd->harq_size, ppWritePackedMsg, end)); -} -static uint8_t pack_ul_config_request_harq_info_rel9_fdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_harq_information_rel9_fdd_t* harq_info_rel9_fdd = (nfapi_ul_config_harq_information_rel9_fdd_t*)tlv; - - return ( push8(harq_info_rel9_fdd->harq_size, ppWritePackedMsg, end) && - push8(harq_info_rel9_fdd->ack_nack_mode, ppWritePackedMsg, end) && - push8(harq_info_rel9_fdd->number_of_pucch_resources, ppWritePackedMsg, end) && - push16(harq_info_rel9_fdd->n_pucch_1_0, ppWritePackedMsg, end) && - push16(harq_info_rel9_fdd->n_pucch_1_1, ppWritePackedMsg, end) && - push16(harq_info_rel9_fdd->n_pucch_1_2, ppWritePackedMsg, end) && - push16(harq_info_rel9_fdd->n_pucch_1_3, ppWritePackedMsg, end)); -} -static uint8_t pack_ul_config_request_harq_info_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_harq_information_rel11_t* harq_info_rel11 = (nfapi_ul_config_harq_information_rel11_t*)tlv; - - return ( push8(harq_info_rel11->num_ant_ports, ppWritePackedMsg, end) && - push16(harq_info_rel11->n_pucch_2_0, ppWritePackedMsg, end) && - push16(harq_info_rel11->n_pucch_2_1, ppWritePackedMsg, end) && - push16(harq_info_rel11->n_pucch_2_2, ppWritePackedMsg, end) && - push16(harq_info_rel11->n_pucch_2_3, ppWritePackedMsg, end)); -} -static uint8_t pack_ul_config_request_harq_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_harq_information_rel13_t*)tlv; - - return ( push16(harq_info_rel13->harq_size_2, ppWritePackedMsg, end) && - push8(harq_info_rel13->starting_prb, ppWritePackedMsg, end) && - push8(harq_info_rel13->n_prb, ppWritePackedMsg, end) && - push8(harq_info_rel13->cdm_index, ppWritePackedMsg, end) && - push8(harq_info_rel13->n_srs, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_harq_information(nfapi_ul_config_harq_information* harq_info, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG, &harq_info->harq_information_rel10_tdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel10_tdd_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG, &harq_info->harq_information_rel8_fdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel8_fdd_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG, &harq_info->harq_information_rel9_fdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel9_fdd_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG, &harq_info->harq_information_rel11, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel11_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG, &harq_info->harq_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel13_value)); - -} - -static uint8_t pack_ul_config_request_cqi_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_information_rel8_t* cqi_info_rel8 = (nfapi_ul_config_cqi_information_rel8_t*)tlv; - - return ( push16(cqi_info_rel8->pucch_index, ppWritePackedMsg, end) && - push8(cqi_info_rel8->dl_cqi_pmi_size, ppWritePackedMsg, end)); -} -static uint8_t pack_ul_config_request_cqi_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_information_rel10_t* cqi_info_rel10 = (nfapi_ul_config_cqi_information_rel10_t*)tlv; - - return ( push8(cqi_info_rel10->number_of_pucch_resource, ppWritePackedMsg, end) && - push16(cqi_info_rel10->pucch_index_p1, ppWritePackedMsg, end)); -} -static uint8_t pack_ul_config_request_cqi_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_information_rel13_t* cqi_info_rel13 = (nfapi_ul_config_cqi_information_rel13_t*)tlv; - - return ( push8(cqi_info_rel13->csi_mode, ppWritePackedMsg, end) && - push16(cqi_info_rel13->dl_cqi_pmi_size_2, ppWritePackedMsg, end) && - push8(cqi_info_rel13->starting_prb, ppWritePackedMsg, end) && - push8(cqi_info_rel13->n_prb, ppWritePackedMsg, end) && - push8(cqi_info_rel13->cdm_index, ppWritePackedMsg, end) && - push8(cqi_info_rel13->n_srs, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_cqi_information(nfapi_ul_config_cqi_information* cqi_info, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG, &cqi_info->cqi_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel8_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG, &cqi_info->cqi_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel10_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG, &cqi_info->cqi_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel13_value)); - -} - -static uint8_t pack_ul_config_request_sr_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_sr_information_rel8_t* sr_info_rel8 = (nfapi_ul_config_sr_information_rel8_t*)tlv; - return push16(sr_info_rel8->pucch_index, ppWritePackedMsg, end); -} -static uint8_t pack_ul_config_request_sr_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_sr_information_rel10_t* sr_info_rel10 = (nfapi_ul_config_sr_information_rel10_t*)tlv; - - return ( push8(sr_info_rel10->number_of_pucch_resources, ppWritePackedMsg, end) && - push16(sr_info_rel10->pucch_index_p1, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_sr_information(nfapi_ul_config_sr_information* sr_info, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG, &sr_info->sr_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_sr_info_rel8_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG, &sr_info->sr_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_sr_info_rel10_value)); -} - -static uint8_t pack_ul_config_request_srs_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_srs_pdu_rel8_t* srs_pdu_rel8 = (nfapi_ul_config_srs_pdu_rel8_t*)tlv; - - return (push32(srs_pdu_rel8->handle, ppWritePackedMsg, end) && - push16(srs_pdu_rel8->size, ppWritePackedMsg, end) && - push16(srs_pdu_rel8->rnti, ppWritePackedMsg, end) && - push8(srs_pdu_rel8->srs_bandwidth, ppWritePackedMsg, end) && - push8(srs_pdu_rel8->frequency_domain_position, ppWritePackedMsg, end) && - push8(srs_pdu_rel8->srs_hopping_bandwidth, ppWritePackedMsg, end) && - push8(srs_pdu_rel8->transmission_comb, ppWritePackedMsg, end) && - push16(srs_pdu_rel8->i_srs, ppWritePackedMsg, end) && - push8(srs_pdu_rel8->sounding_reference_cyclic_shift, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_srs_pdu_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_srs_pdu_rel10_t* srs_pdu_rel10 = (nfapi_ul_config_srs_pdu_rel10_t*)tlv; - return push8(srs_pdu_rel10->antenna_port, ppWritePackedMsg, end); -} - -static uint8_t pack_ul_config_request_srs_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_srs_pdu_rel13_t* srs_pdu_rel13 = (nfapi_ul_config_srs_pdu_rel13_t*)tlv; - - return ( push8(srs_pdu_rel13->number_of_combs, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_nb_harq_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_nb_harq_information_rel13_fdd_t* nb_harq_pdu_rel13 = (nfapi_ul_config_nb_harq_information_rel13_fdd_t*)tlv; - - return ( push8(nb_harq_pdu_rel13->harq_ack_resource, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_config_request_nulsch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_nulsch_pdu_rel13_t* nulsch_pdu_rel13 = (nfapi_ul_config_nulsch_pdu_rel13_t*)tlv; - - return (push8(nulsch_pdu_rel13->nulsch_format, ppWritePackedMsg, end) && - push32(nulsch_pdu_rel13->handle, ppWritePackedMsg, end) && - push16(nulsch_pdu_rel13->size, ppWritePackedMsg, end) && - push16(nulsch_pdu_rel13->rnti, ppWritePackedMsg, end) && - push8(nulsch_pdu_rel13->subcarrier_indication, ppWritePackedMsg, end) && - push8(nulsch_pdu_rel13->resource_assignment, ppWritePackedMsg, end) && - push8(nulsch_pdu_rel13->mcs, ppWritePackedMsg, end) && - push8(nulsch_pdu_rel13->redudancy_version, ppWritePackedMsg, end) && - push8(nulsch_pdu_rel13->repetition_number, ppWritePackedMsg, end) && - push8(nulsch_pdu_rel13->new_data_indication, ppWritePackedMsg, end) && - push8(nulsch_pdu_rel13->n_srs, ppWritePackedMsg, end) && - push16(nulsch_pdu_rel13->scrambling_sequence_initialization_cinit, ppWritePackedMsg, end) && - push16(nulsch_pdu_rel13->sf_idx, ppWritePackedMsg, end) && - pack_ul_config_request_ue_information(&(nulsch_pdu_rel13->ue_information), ppWritePackedMsg, end) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG, &nulsch_pdu_rel13->nb_harq_information.nb_harq_information_rel13_fdd, ppWritePackedMsg, end, &pack_ul_config_request_nb_harq_rel13_value)); -} -static uint8_t pack_ul_config_request_nrach_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_nrach_pdu_rel13_t* nrach_pdu_rel13 = (nfapi_ul_config_nrach_pdu_rel13_t*)tlv; - - return ( push8(nrach_pdu_rel13->nprach_config_0, ppWritePackedMsg, end) && - push8(nrach_pdu_rel13->nprach_config_1, ppWritePackedMsg, end) && - push8(nrach_pdu_rel13->nprach_config_2, ppWritePackedMsg, end)); - -} - -static uint8_t pack_ul_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_config_request_body_t* value = (nfapi_ul_config_request_body_t*)tlv; - - if(!(push8(value->number_of_pdus, ppWritePackedMsg, end) && - push8(value->rach_prach_frequency_resources, ppWritePackedMsg, end) && - push8(value->srs_present, ppWritePackedMsg, end))) - return 0; - - uint16_t i = 0; - for(i = 0; i < value->number_of_pdus; ++i) - { - nfapi_ul_config_request_pdu_t* pdu = &(value->ul_config_pdu_list[i]); - - if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) - return 0; - - // Put a 0 size in and then determine the size after the pdu - // has been writen and write the calculated size - uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; - pdu->pdu_size = 0; - if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) - return 0; - - switch(pdu->pdu_type) - { - case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: - { - if(!pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_pdu), ppWritePackedMsg, end)) - return 0; - } - break; - case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: - { - if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_cqi_ri_pdu.ulsch_pdu), ppWritePackedMsg, end) && - pack_ul_config_request_cqi_ri_information(&(pdu->ulsch_cqi_ri_pdu.cqi_ri_information), ppWritePackedMsg, end) && - pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_cqi_ri_pdu.initial_transmission_parameters), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: - { - if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) && - pack_ul_config_request_ulsch_harq_information(&(pdu->ulsch_harq_pdu.harq_information), ppWritePackedMsg, end) && - pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_harq_pdu.initial_transmission_parameters), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: - { - if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu), ppWritePackedMsg, end) && - pack_ul_config_request_cqi_ri_information(&(pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information), ppWritePackedMsg, end) && - pack_ul_config_request_ulsch_harq_information(&(pdu->ulsch_cqi_harq_ri_pdu.harq_information), ppWritePackedMsg, end) && - pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: - { - if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_pdu.ue_information), ppWritePackedMsg, end) && - pack_ul_config_request_cqi_information(&(pdu->uci_cqi_pdu.cqi_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: - { - if(!(pack_ul_config_request_ue_information(&(pdu->uci_sr_pdu.ue_information), ppWritePackedMsg, end) && - pack_ul_config_request_sr_information(&(pdu->uci_sr_pdu.sr_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: - { - if(!(pack_ul_config_request_ue_information(&(pdu->uci_harq_pdu.ue_information), ppWritePackedMsg, end) && - pack_ul_config_request_harq_information(&(pdu->uci_harq_pdu.harq_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: - { - if(!(pack_ul_config_request_ue_information(&(pdu->uci_sr_harq_pdu.ue_information), ppWritePackedMsg, end) && - pack_ul_config_request_sr_information(&(pdu->uci_sr_harq_pdu.sr_information), ppWritePackedMsg, end) && - pack_ul_config_request_harq_information(&(pdu->uci_sr_harq_pdu.harq_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: - { - if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_harq_pdu.ue_information), ppWritePackedMsg, end) && - pack_ul_config_request_cqi_information(&(pdu->uci_cqi_harq_pdu.cqi_information), ppWritePackedMsg, end) && - pack_ul_config_request_harq_information(&(pdu->uci_cqi_harq_pdu.harq_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: - { - if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_sr_pdu.ue_information), ppWritePackedMsg, end) && - pack_ul_config_request_cqi_information(&(pdu->uci_cqi_sr_pdu.cqi_information), ppWritePackedMsg, end) && - pack_ul_config_request_sr_information(&(pdu->uci_cqi_sr_pdu.sr_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: - { - if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_sr_harq_pdu.ue_information), ppWritePackedMsg, end) && - pack_ul_config_request_cqi_information(&(pdu->uci_cqi_sr_harq_pdu.cqi_information), ppWritePackedMsg, end) && - pack_ul_config_request_sr_information(&(pdu->uci_cqi_sr_harq_pdu.sr_information), ppWritePackedMsg, end) && - pack_ul_config_request_harq_information(&(pdu->uci_cqi_sr_harq_pdu.harq_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_SRS_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG, &pdu->srs_pdu.srs_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel8_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG, &pdu->srs_pdu.srs_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel10_value) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG, &pdu->srs_pdu.srs_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel13_value))) - return 0; - } - break; - case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: - { - if(!(pack_ul_config_request_ue_information(&(pdu->harq_buffer_pdu.ue_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: - { - if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_uci_csi_pdu.ulsch_pdu), ppWritePackedMsg, end) && - pack_ul_config_request_cqi_information(&(pdu->ulsch_uci_csi_pdu.csi_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: - { - if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_uci_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) && - pack_ul_config_request_harq_information(&(pdu->ulsch_uci_harq_pdu.harq_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: - { - if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) && - pack_ul_config_request_cqi_information(&(pdu->ulsch_csi_uci_harq_pdu.csi_information), ppWritePackedMsg, end) && - pack_ul_config_request_harq_information(&(pdu->ulsch_csi_uci_harq_pdu.harq_information), ppWritePackedMsg, end))) - return 0; - } - break; - case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG, &pdu->nulsch_pdu.nulsch_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_nulsch_pdu_rel13_value))) - return 0; - } - break; - case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG, &pdu->nrach_pdu.nrach_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_nrach_pdu_rel13_value))) - return 0; - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); - } - break; - }; - - // add 1 for the pdu_type. The delta will include the pdu_size - pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); - push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); - - } - return 1; -} - -static uint8_t pack_ul_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_UL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->ul_config_request_body, ppWritePackedMsg, end, &pack_ul_config_request_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)) ; -} - -static uint8_t pack_hi_dci0_hi_rel8_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_hi_pdu_rel8_t* hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t*)tlv; - - return ( push8(hi_pdu_rel8->resource_block_start, ppWritePackedMsg, end) && - push8(hi_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) && - push8(hi_pdu_rel8->hi_value, ppWritePackedMsg, end) && - push8(hi_pdu_rel8->i_phich, ppWritePackedMsg, end) && - push16(hi_pdu_rel8->transmission_power, ppWritePackedMsg, end)); -} - -static uint8_t pack_hi_dci0_hi_rel10_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_hi_pdu_rel10_t* hi_pdu_rel10 = (nfapi_hi_dci0_hi_pdu_rel10_t*)tlv; - - return ( push8(hi_pdu_rel10->flag_tb2, ppWritePackedMsg, end) && - push8(hi_pdu_rel10->hi_value_2, ppWritePackedMsg, end)); -} - -static uint8_t pack_hi_dci0_dci_rel8_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_dci_pdu_rel8_t* dci_pdu_rel8 = (nfapi_hi_dci0_dci_pdu_rel8_t*)tlv; - - return ( push8(dci_pdu_rel8->dci_format, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->cce_index, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->aggregation_level, ppWritePackedMsg, end) && - push16(dci_pdu_rel8->rnti, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->resource_block_start, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->number_of_resource_block, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->mcs_1, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->frequency_hopping_enabled_flag, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->frequency_hopping_bits, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->new_data_indication_1, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->ue_tx_antenna_seleciton, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->tpc, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->cqi_csi_request, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->ul_index, ppWritePackedMsg, end) && - push8(dci_pdu_rel8->dl_assignment_index, ppWritePackedMsg, end) && - push32(dci_pdu_rel8->tpc_bitmap, ppWritePackedMsg, end) && - push16(dci_pdu_rel8->transmission_power, ppWritePackedMsg, end)); -} - -static uint8_t pack_hi_dci0_dci_rel10_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_dci_pdu_rel10_t* dci_pdu_rel10 = (nfapi_hi_dci0_dci_pdu_rel10_t*)tlv; - - return ( push8(dci_pdu_rel10->cross_carrier_scheduling_flag, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->carrier_indicator, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->size_of_cqi_csi_feild, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->srs_flag, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->srs_request, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->resource_allocation_flag, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->resource_allocation_type, ppWritePackedMsg, end) && - push32(dci_pdu_rel10->resource_block_coding, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->mcs_2, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->new_data_indication_2, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->number_of_antenna_ports, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->tpmi, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->total_dci_length_including_padding, ppWritePackedMsg, end) && - push8(dci_pdu_rel10->n_ul_rb, ppWritePackedMsg, end)); -} - -static uint8_t pack_hi_dci0_dci_rel12_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_dci_pdu_rel12_t* dci_pdu_rel12 = (nfapi_hi_dci0_dci_pdu_rel12_t*)tlv; - - return ( push8(dci_pdu_rel12->pscch_resource, ppWritePackedMsg, end) && - push8(dci_pdu_rel12->time_resource_pattern, ppWritePackedMsg, end)); -} - -static uint8_t pack_hi_dci0_mpdcch_dci_rel13_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t* mpdcch_dci_pdu_rel13 = (nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t*)tlv; - - return ( push8(mpdcch_dci_pdu_rel13->mpdcch_narrowband, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->number_of_prb_pairs, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->resource_block_assignment, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->mpdcch_transmission_type, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->start_symbol, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->ecce_index, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->aggreagation_level, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->rnti_type, ppWritePackedMsg, end) && - push16(mpdcch_dci_pdu_rel13->rnti, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->ce_mode, ppWritePackedMsg, end) && - push16(mpdcch_dci_pdu_rel13->drms_scrambling_init, ppWritePackedMsg, end) && - push16(mpdcch_dci_pdu_rel13->initial_transmission_sf_io, ppWritePackedMsg, end) && - push16(mpdcch_dci_pdu_rel13->transmission_power, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->dci_format, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->resource_block_start, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->number_of_resource_blocks, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->mcs, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->pusch_repetition_levels, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->frequency_hopping_flag, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->new_data_indication, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->harq_process, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->redudency_version, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->tpc, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->csi_request, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->ul_inex, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->dai_presence_flag, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->dl_assignment_index, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->srs_request, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->dci_subframe_repetition_number, ppWritePackedMsg, end) && - push32(mpdcch_dci_pdu_rel13->tcp_bitmap, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->total_dci_length_include_padding, ppWritePackedMsg, end) && - push8(mpdcch_dci_pdu_rel13->number_of_tx_antenna_ports, ppWritePackedMsg, end) && - pusharray16(mpdcch_dci_pdu_rel13->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, mpdcch_dci_pdu_rel13->number_of_tx_antenna_ports, ppWritePackedMsg, end)); - -} - -static uint8_t pack_hi_dci0_npdcch_dci_rel13_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_npdcch_dci_pdu_rel13_t* npdcch_dci_pdu_rel13 = (nfapi_hi_dci0_npdcch_dci_pdu_rel13_t*)tlv; - - return ( push8(npdcch_dci_pdu_rel13->ncce_index, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->aggregation_level, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->start_symbol, ppWritePackedMsg, end) && - push16(npdcch_dci_pdu_rel13->rnti, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->scrambling_reinitialization_batch_index, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->subcarrier_indication, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->resource_assignment, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->scheduling_delay, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->mcs, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->redudancy_version, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->repetition_number, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->new_data_indicator, ppWritePackedMsg, end) && - push8(npdcch_dci_pdu_rel13->dci_subframe_repetition_number, ppWritePackedMsg, end)); -} - - -static uint8_t pack_hi_dci0_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_request_body_t* value = (nfapi_hi_dci0_request_body_t*)tlv; - - if(!(push16(value->sfnsf, ppWritePackedMsg, end) && - push8(value->number_of_dci, ppWritePackedMsg, end) && - push8(value->number_of_hi, ppWritePackedMsg, end))) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_pdus = value->number_of_dci + value->number_of_hi; - for(i = 0; i < total_number_of_pdus; ++i) - { - nfapi_hi_dci0_request_pdu_t* pdu = &(value->hi_dci0_pdu_list[i]); - - if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) - return 0; - - // Put a 0 size in and then determine the size after the pdu - // has been writen and write the calculated size - uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; - pdu->pdu_size = 0; - if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) - return 0; - - switch(pdu->pdu_type) - { - case NFAPI_HI_DCI0_HI_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG, &pdu->hi_pdu.hi_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_hi_rel8_pdu_value) && - pack_tlv(NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG, &pdu->hi_pdu.hi_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_hi_rel10_pdu_value))) - return 0; - } - break; - case NFAPI_HI_DCI0_DCI_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG, &pdu->dci_pdu.dci_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_dci_rel8_pdu_value) && - pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG, &pdu->dci_pdu.dci_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_dci_rel10_pdu_value) && - pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG, &pdu->dci_pdu.dci_pdu_rel12, ppWritePackedMsg, end, pack_hi_dci0_dci_rel12_pdu_value))) - return 0; - } - break; - case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_dci_rel8_pdu_value) && - pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_dci_rel10_pdu_value) && - pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG, &pdu->epdcch_dci_pdu.epdcch_parameters_rel11, ppWritePackedMsg, end, pack_dl_config_epdcch_parameters_rel11_value))) - return 0; - } - break; - case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG, &pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13, ppWritePackedMsg, end, pack_hi_dci0_mpdcch_dci_rel13_pdu_value))) - return 0; - } - break; - case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: - { - if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG, &pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13, ppWritePackedMsg, end, pack_hi_dci0_npdcch_dci_rel13_pdu_value))) - return 0; - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); - } - break; - }; - - // add 1 for the pdu_type. The delta will include the pdu_size - pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); - push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); - - } - - return 1; -} - -static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_HI_DCI0_REQUEST_BODY_TAG, &pNfapiMsg->hi_dci0_request_body, ppWritePackedMsg, end, &pack_hi_dci0_request_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - -static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_tx_request_body_t* value = (nfapi_tx_request_body_t*)tlv; - - if(push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_pdus = value->number_of_pdus; - for(; i < total_number_of_pdus; ++i) - { - nfapi_tx_request_pdu_t* pdu = &(value->tx_pdu_list[i]); - - if(!(push16(pdu->pdu_length, ppWritePackedMsg, end) && - push16(pdu->pdu_index, ppWritePackedMsg, end))) - return 0; - - uint8_t j; - for(j = 0; j < pdu->num_segments; ++j) - { - // Use -1 as it is unbounded - // DJP - does not handle -1 - // DJP - if(pusharray8(pdu->segments[j].segment_data, (uint32_t)(-1), pdu->segments[j].segment_length, ppWritePackedMsg, end) == 0) - int push_ret = pusharray8(pdu->segments[j].segment_data, 65535, pdu->segments[j].segment_length, ppWritePackedMsg, end); - + } +} + +void nfapi_p7_deallocate(void* ptr, nfapi_p7_codec_config_t* config) +{ + if(ptr == NULL) + return; + + if(config && config->deallocate) + { + return (config->deallocate)(ptr); + } + else + { + return free(ptr); + } +} +// Pack routines + + +static uint8_t pack_dl_config_dci_dl_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel8_t* value = (nfapi_dl_config_dci_dl_pdu_rel8_t*)tlv; + + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci_format:%u\n", __FUNCTION__, value->dci_format); + + return ( push8(value->dci_format, ppWritePackedMsg, end) && + push8(value->cce_idx, ppWritePackedMsg, end) && + push8(value->aggregation_level, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push8(value->resource_allocation_type, ppWritePackedMsg, end) && + push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) && + push32(value->resource_block_coding, ppWritePackedMsg, end) && + push8(value->mcs_1, ppWritePackedMsg, end) && + push8(value->redundancy_version_1, ppWritePackedMsg, end) && + push8(value->new_data_indicator_1, ppWritePackedMsg, end) && + push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) && + push8(value->mcs_2, ppWritePackedMsg, end) && + push8(value->redundancy_version_2, ppWritePackedMsg, end) && + push8(value->new_data_indicator_2, ppWritePackedMsg, end) && + push8(value->harq_process, ppWritePackedMsg, end) && + push8(value->tpmi, ppWritePackedMsg, end) && + push8(value->pmi, ppWritePackedMsg, end) && + push8(value->precoding_information, ppWritePackedMsg, end) && + push8(value->tpc, ppWritePackedMsg, end) && + push8(value->downlink_assignment_index, ppWritePackedMsg, end) && + push8(value->ngap, ppWritePackedMsg, end) && + push8(value->transport_block_size_index, ppWritePackedMsg, end) && + push8(value->downlink_power_offset, ppWritePackedMsg, end) && + push8(value->allocate_prach_flag, ppWritePackedMsg, end) && + push8(value->preamble_index, ppWritePackedMsg, end) && + push8(value->prach_mask_index, ppWritePackedMsg, end) && + push8(value->rnti_type, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_dci_dl_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel9_t* value = (nfapi_dl_config_dci_dl_pdu_rel9_t*)tlv; + + return( push8(value->mcch_flag, ppWritePackedMsg, end) && + push8(value->mcch_change_notification, ppWritePackedMsg, end) && + push8(value->scrambling_identity, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_dci_dl_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel10_t* value = (nfapi_dl_config_dci_dl_pdu_rel10_t*)tlv; + + return ( push8(value->cross_carrier_scheduling_flag, ppWritePackedMsg, end) && + push8(value->carrier_indicator, ppWritePackedMsg, end) && + push8(value->srs_flag, ppWritePackedMsg, end) && + push8(value->srs_request, ppWritePackedMsg, end) && + push8(value->antenna_ports_scrambling_and_layers, ppWritePackedMsg, end) && + push8(value->total_dci_length_including_padding, ppWritePackedMsg, end) && + push8(value->n_dl_rb, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_dci_dl_pdu_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel11_t* value = (nfapi_dl_config_dci_dl_pdu_rel11_t*)tlv; + + return ( push8(value->harq_ack_resource_offset, ppWritePackedMsg, end) && + push8(value->pdsch_re_mapping_quasi_co_location_indicator, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_dci_dl_pdu_rel12_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel12_t* value = (nfapi_dl_config_dci_dl_pdu_rel12_t*)tlv; + + return ( push8(value->primary_cell_type, ppWritePackedMsg, end) && + push8(value->ul_dl_configuration_flag, ppWritePackedMsg, end) && + push8(value->number_ul_dl_configurations, ppWritePackedMsg, end) && + pusharray8(value->ul_dl_configuration_indication, NFAPI_MAX_UL_DL_CONFIGURATIONS, value->number_ul_dl_configurations, ppWritePackedMsg, end)); +} + +static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t* value, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + if (!( push8(value->num_prb_per_subband, ppWritePackedMsg, end) && + push8(value->number_of_subbands, ppWritePackedMsg, end) && + push8(value->num_antennas, ppWritePackedMsg, end))) + return 0; + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_subbands; ++idx) + { + nfapi_dl_config_dci_dl_tpm_subband_info_t* subband_info = &(value->subband_info[idx]); + + if(!(push8(subband_info->subband_index, ppWritePackedMsg, end) && + push8(subband_info->scheduled_ues, ppWritePackedMsg, end))) + return 0; + + + uint8_t antenna_idx = 0; + uint8_t scheduled_ue_idx = 0; + + for(antenna_idx = 0; antenna_idx < value->num_antennas; ++antenna_idx) + { + for(scheduled_ue_idx = 0; scheduled_ue_idx < subband_info->scheduled_ues; ++scheduled_ue_idx) + { + if(!push16(subband_info->precoding_value[antenna_idx][scheduled_ue_idx], ppWritePackedMsg, end)) + return 0; + } + } + + } + + + return 1; + +} + + +static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_csi_rs_pdu_rel15_t* value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t*)tlv; + + return( + push16(value->bwp_size, ppWritePackedMsg, end) && + push16(value->bwp_start, ppWritePackedMsg, end) && + + push8(value->subcarrier_spacing, ppWritePackedMsg, end) && + push8(value->cyclic_prefix, ppWritePackedMsg, end) && + + push16(value->start_rb, ppWritePackedMsg, end) && + push16(value->nr_of_rbs, ppWritePackedMsg, end) && + + push8(value->csi_type, ppWritePackedMsg, end) && + push8(value->row, ppWritePackedMsg, end) && + + push16(value->freq_domain, ppWritePackedMsg, end) && + push8(value->symb_l0, ppWritePackedMsg, end) && + + push8(value->symb_l1, ppWritePackedMsg, end) && + push8(value->cdm_type, ppWritePackedMsg, end) && + + push8(value->freq_density, ppWritePackedMsg, end) && + push16(value->scramb_id, ppWritePackedMsg, end) && + + push8(value->power_control_offset, ppWritePackedMsg, end) && + push8(value->power_control_offset_ss, ppWritePackedMsg, end) + ); + +} + + +static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_pdcch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t*)tlv; + + for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) + { + if(!push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) && + push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end) && + + push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) && + push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end) && + push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end) && + push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) && + + push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) && + push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) && + pusharray8(value->dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end)); + + return 0; + } + + // TODO: resolve the packaging of array (currently sending a single element) + return( + push16(value->BWPSize, ppWritePackedMsg, end) && + push16(value->BWPStart, ppWritePackedMsg, end) && + push8(value->SubcarrierSpacing, ppWritePackedMsg, end) && + push8(value->CyclicPrefix, ppWritePackedMsg, end) && + + push8(value->StartSymbolIndex, ppWritePackedMsg, end) && + push8(value->DurationSymbols, ppWritePackedMsg, end) && + pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end) && + push8(value->CceRegMappingType, ppWritePackedMsg, end) && + + push8(value->RegBundleSize, ppWritePackedMsg, end) && + push8(value->InterleaverSize, ppWritePackedMsg, end) && + push8(value->CoreSetType, ppWritePackedMsg, end) && + push16(value->ShiftIndex, ppWritePackedMsg, end) && + + push8(value->precoderGranularity, ppWritePackedMsg, end) && + push16(value->numDlDci, ppWritePackedMsg, end)); + +} + + +static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_pdsch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t*)tlv; + + // TODO: resolve the packaging of array (currently sending a single element) + return( + push16(value->pduBitmap, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push16(value->pduIndex, ppWritePackedMsg, end) && + push16(value->BWPSize, ppWritePackedMsg, end) && + + push16(value->BWPStart, ppWritePackedMsg, end) && + push8(value->SubcarrierSpacing, ppWritePackedMsg, end) && + push8(value->CyclicPrefix, ppWritePackedMsg, end) && + push8(value->NrOfCodewords, ppWritePackedMsg, end) && + + pusharray16(value->targetCodeRate, 2, 1, ppWritePackedMsg, end) && + pusharray8(value->qamModOrder, 2, 1, ppWritePackedMsg, end) && + pusharray8(value->mcsIndex, 2, 1, ppWritePackedMsg, end) && + pusharray8(value->mcsTable, 2, 1, ppWritePackedMsg, end) && + + pusharray8(value->rvIndex, 2, 1, ppWritePackedMsg, end) && + pusharray32(value->TBSize, 2, 1, ppWritePackedMsg, end) && + push16(value->dataScramblingId, ppWritePackedMsg, end) && + push8(value->nrOfLayers, ppWritePackedMsg, end) && + + push8(value->transmissionScheme, ppWritePackedMsg, end) && + push8(value->refPoint, ppWritePackedMsg, end) && + push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) && + push8(value->dmrsConfigType, ppWritePackedMsg, end) && + + push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) && + push8(value->SCID, ppWritePackedMsg, end) && + push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) && + push16(value->dmrsPorts, ppWritePackedMsg, end) && + + push8(value->resourceAlloc, ppWritePackedMsg, end) && + push16(value->rbStart, ppWritePackedMsg, end) && + push16(value->rbSize, ppWritePackedMsg, end) && + + push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) && + push8(value->StartSymbolIndex, ppWritePackedMsg, end) && + push8(value->NrOfSymbols, ppWritePackedMsg, end) && + push8(value->PTRSPortIndex, ppWritePackedMsg, end) && + + push8(value->PTRSTimeDensity, ppWritePackedMsg, end) && + push8(value->PTRSFreqDensity, ppWritePackedMsg, end) && + push8(value->PTRSReOffset, ppWritePackedMsg, end) + ); + +} + + +static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_ssb_pdu_rel15_t* value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t*)tlv; + + return( + push16(value->PhysCellId, ppWritePackedMsg, end) && + push8(value->BetaPss, ppWritePackedMsg, end) && + push8(value->SsbBlockIndex, ppWritePackedMsg, end) && + push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end) && + push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && + push8(value->bchPayloadFlag, ppWritePackedMsg, end) && + push32(value->bchPayload, ppWritePackedMsg, end) + // TODO: pack precoding_and_beamforming too + ); + +} + + +static uint8_t pack_dl_config_dci_dl_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel13_t* value = (nfapi_dl_config_dci_dl_pdu_rel13_t*)tlv; + + return( push8(value->laa_end_partial_sf_flag, ppWritePackedMsg, end) && + push8(value->laa_end_partial_sf_configuration, ppWritePackedMsg, end) && + push8(value->initial_lbt_sf, ppWritePackedMsg, end) && + push8(value->codebook_size_determination, ppWritePackedMsg, end) && + push8(value->drms_table_flag, ppWritePackedMsg, end) && + push8(value->tpm_struct_flag, ppWritePackedMsg, end) && + (value->tpm_struct_flag == 1 ? pack_tpm_value(&(value->tpm), ppWritePackedMsg, end) : 1)); +} + +static uint8_t pack_dl_config_bch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_bch_pdu_rel8_t* value = (nfapi_dl_config_bch_pdu_rel8_t*)tlv; + + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s()\n", __FUNCTION__); + + return( push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_mch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_mch_pdu_rel8_t* value = (nfapi_dl_config_mch_pdu_rel8_t*)tlv; + + return ( push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push8(value->resource_allocation_type, ppWritePackedMsg, end) && + push32(value->resource_block_coding, ppWritePackedMsg, end) && + push8(value->modulation, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end) && + push16(value->mbsfn_area_id, ppWritePackedMsg, end)); +} + +static uint8_t pack_bf_vector_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_bf_vector_t* bf = (nfapi_bf_vector_t*)elem; + + return ( push8(bf->subband_index, ppWritePackedMsg, end) && + push8(bf->num_antennas, ppWritePackedMsg, end) && + pusharray16(bf->bf_value, NFAPI_MAX_NUM_ANTENNAS, bf->num_antennas, ppWritePackedMsg, end)); + + +} +static uint8_t pack_dl_config_dlsch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel8_t* value = (nfapi_dl_config_dlsch_pdu_rel8_t*)tlv; + + return ( push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push8(value->resource_allocation_type, ppWritePackedMsg, end) && + push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) && + push32(value->resource_block_coding, ppWritePackedMsg, end) && + push8(value->modulation, ppWritePackedMsg, end) && + push8(value->redundancy_version, ppWritePackedMsg, end) && + push8(value->transport_blocks, ppWritePackedMsg, end) && + push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) && + push8(value->transmission_scheme, ppWritePackedMsg, end) && + push8(value->number_of_layers, ppWritePackedMsg, end) && + push8(value->number_of_subbands, ppWritePackedMsg, end) && + pusharray8(value->codebook_index, NFAPI_MAX_NUM_SUBBANDS, value->number_of_subbands, ppWritePackedMsg, end) && + push8(value->ue_category_capacity, ppWritePackedMsg, end) && + push8(value->pa, ppWritePackedMsg, end) && + push8(value->delta_power_offset_index, ppWritePackedMsg, end) && + push8(value->ngap, ppWritePackedMsg, end) && + push8(value->nprb, ppWritePackedMsg, end) && + push8(value->transmission_mode, ppWritePackedMsg, end) && + push8(value->num_bf_prb_per_subband, ppWritePackedMsg, end) && + push8(value->num_bf_vector, ppWritePackedMsg, end) && + packarray(value->bf_vector, sizeof(nfapi_bf_vector_t), NFAPI_MAX_BF_VECTORS, value->num_bf_vector, ppWritePackedMsg, end, &pack_bf_vector_info)); + +} +static uint8_t pack_dl_config_dlsch_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel9_t* value = (nfapi_dl_config_dlsch_pdu_rel9_t*)tlv; + return ( push8(value->nscid, ppWritePackedMsg, end) ); +} +static uint8_t pack_dl_config_dlsch_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel10_t* value = (nfapi_dl_config_dlsch_pdu_rel10_t*)tlv; + + return ( push8(value->csi_rs_flag, ppWritePackedMsg, end) && + push8(value->csi_rs_resource_config_r10, ppWritePackedMsg, end) && + push16(value->csi_rs_zero_tx_power_resource_config_bitmap_r10, ppWritePackedMsg, end) && + push8(value->csi_rs_number_nzp_configuration, ppWritePackedMsg, end) && + pusharray8(value->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, value->csi_rs_number_nzp_configuration, ppWritePackedMsg, end) && + push8(value->pdsch_start, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_dlsch_pdu_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel11_t* value = (nfapi_dl_config_dlsch_pdu_rel11_t*)tlv; + + return( push8(value->drms_config_flag, ppWritePackedMsg, end) && + push16(value->drms_scrambling, ppWritePackedMsg, end) && + push8(value->csi_config_flag, ppWritePackedMsg, end) && + push16(value->csi_scrambling, ppWritePackedMsg, end) && + push8(value->pdsch_re_mapping_flag, ppWritePackedMsg, end) && + push8(value->pdsch_re_mapping_atenna_ports, ppWritePackedMsg, end) && + push8(value->pdsch_re_mapping_freq_shift, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_dlsch_pdu_rel12_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel12_t* value = (nfapi_dl_config_dlsch_pdu_rel12_t*)tlv; + + return( push8(value->altcqi_table_r12, ppWritePackedMsg, end) && + push8(value->maxlayers, ppWritePackedMsg, end) && + push8(value->n_dl_harq, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_dlsch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel13_t* value = (nfapi_dl_config_dlsch_pdu_rel13_t*)tlv; + + return( push8(value->dwpts_symbols, ppWritePackedMsg, end) && + push8(value->initial_lbt_sf, ppWritePackedMsg, end) && + push8(value->ue_type, ppWritePackedMsg, end) && + push8(value->pdsch_payload_type, ppWritePackedMsg, end) && + push16(value->initial_transmission_sf_io, ppWritePackedMsg, end) && + push8(value->drms_table_flag, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_pch_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_pch_pdu_rel8_t* value = (nfapi_dl_config_pch_pdu_rel8_t*)tlv; + + return( push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->p_rnti, ppWritePackedMsg, end) && + push8(value->resource_allocation_type, ppWritePackedMsg, end) && + push8(value->virtual_resource_block_assignment_flag, ppWritePackedMsg, end) && + push32(value->resource_block_coding, ppWritePackedMsg, end) && + push8(value->mcs, ppWritePackedMsg, end) && + push8(value->redundancy_version, ppWritePackedMsg, end) && + push8(value->number_of_transport_blocks, ppWritePackedMsg, end) && + push8(value->transport_block_to_codeword_swap_flag, ppWritePackedMsg, end) && + push8(value->transmission_scheme, ppWritePackedMsg, end) && + push8(value->number_of_layers, ppWritePackedMsg, end) && + push8(value->codebook_index, ppWritePackedMsg, end) && + push8(value->ue_category_capacity, ppWritePackedMsg, end) && + push8(value->pa, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end) && + push8(value->nprb, ppWritePackedMsg, end) && + push8(value->ngap, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_pch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_pch_pdu_rel13_t* value = (nfapi_dl_config_pch_pdu_rel13_t*)tlv; + + return ( push8(value->ue_mode, ppWritePackedMsg, end) && + push16(value->initial_transmission_sf_io, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_prs_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_prs_pdu_rel9_t* value = (nfapi_dl_config_prs_pdu_rel9_t*)tlv; + + return( push16(value->transmission_power, ppWritePackedMsg, end) && + push8(value->prs_bandwidth, ppWritePackedMsg, end) && + push8(value->prs_cyclic_prefix_type, ppWritePackedMsg, end) && + push8(value->prs_muting, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_csi_rs_pdu_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_csi_rs_pdu_rel10_t* value = (nfapi_dl_config_csi_rs_pdu_rel10_t*)tlv; + + return( push8(value->csi_rs_antenna_port_count_r10, ppWritePackedMsg, end) && + push8(value->csi_rs_resource_config_r10, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end) && + push16(value->csi_rs_zero_tx_power_resource_config_bitmap_r10, ppWritePackedMsg, end) && + push8(value->csi_rs_number_of_nzp_configuration, ppWritePackedMsg, end) && + pusharray8(value->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, value->csi_rs_number_of_nzp_configuration, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_csi_rs_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_csi_rs_pdu_rel13_t* value = (nfapi_dl_config_csi_rs_pdu_rel13_t*)tlv; + + if(!(push8(value->csi_rs_class, ppWritePackedMsg, end) && + push8(value->cdm_type, ppWritePackedMsg, end) && + push8(value->num_bf_vector, ppWritePackedMsg, end))) + { + return 0; + } + + uint16_t i; + for(i = 0; i < value->num_bf_vector; ++i) + { + if(!(push8(value->bf_vector[i].csi_rs_resource_index, ppWritePackedMsg, end) && + pusharray16(value->bf_vector[i].bf_value, NFAPI_MAX_ANTENNA_PORT_COUNT, NFAPI_MAX_ANTENNA_PORT_COUNT, ppWritePackedMsg, end))) + return 0; + } + + return 1; +} +static uint8_t pack_bf_vector(nfapi_bf_vector_t* vector, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( push8(vector->subband_index, ppWritePackedMsg, end) && + push8(vector->num_antennas, ppWritePackedMsg, end) && + pusharray16(vector->bf_value, NFAPI_MAX_NUM_ANTENNAS, vector->num_antennas, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_epdcch_parameters_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_epdcch_parameters_rel11_t* value = (nfapi_dl_config_epdcch_parameters_rel11_t*)tlv; + + return ( push8(value->epdcch_resource_assignment_flag, ppWritePackedMsg, end) && + push16(value->epdcch_id, ppWritePackedMsg, end) && + push8(value->epdcch_start_symbol, ppWritePackedMsg, end) && + push8(value->epdcch_num_prb, ppWritePackedMsg, end) && + pusharray8(value->epdcch_prb_index, NFAPI_MAX_EPDCCH_PRB, value->epdcch_num_prb, ppWritePackedMsg, end) && + pack_bf_vector(&value->bf_vector, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_epdcch_parameters_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_epdcch_parameters_rel13_t* value = (nfapi_dl_config_epdcch_parameters_rel13_t*)tlv; + + return (push8(value->dwpts_symbols, ppWritePackedMsg, end) && + push8(value->initial_lbt_sf, ppWritePackedMsg, end)); +} +static uint8_t pack_dl_config_mpdcch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_mpdcch_pdu_rel13_t* value = (nfapi_dl_config_mpdcch_pdu_rel13_t*)tlv; + + return ( push8(value->mpdcch_narrow_band, ppWritePackedMsg, end) && + push8(value->number_of_prb_pairs, ppWritePackedMsg, end) && + push8(value->resource_block_assignment, ppWritePackedMsg, end) && + push8(value->mpdcch_tansmission_type, ppWritePackedMsg, end) && + push8(value->start_symbol, ppWritePackedMsg, end) && + push8(value->ecce_index, ppWritePackedMsg, end) && + push8(value->aggregation_level, ppWritePackedMsg, end) && + push8(value->rnti_type, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push8(value->ce_mode, ppWritePackedMsg, end) && + push16(value->drms_scrambling_init, ppWritePackedMsg, end) && + push16(value->initial_transmission_sf_io, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end) && + push8(value->dci_format, ppWritePackedMsg, end) && + push16(value->resource_block_coding, ppWritePackedMsg, end) && + push8(value->mcs, ppWritePackedMsg, end) && + push8(value->pdsch_reptition_levels, ppWritePackedMsg, end) && + push8(value->redundancy_version, ppWritePackedMsg, end) && + push8(value->new_data_indicator, ppWritePackedMsg, end) && + push8(value->harq_process, ppWritePackedMsg, end) && + push8(value->tpmi_length, ppWritePackedMsg, end) && + push8(value->tpmi, ppWritePackedMsg, end) && + push8(value->pmi_flag, ppWritePackedMsg, end) && + push8(value->pmi, ppWritePackedMsg, end) && + push8(value->harq_resource_offset, ppWritePackedMsg, end) && + push8(value->dci_subframe_repetition_number, ppWritePackedMsg, end) && + push8(value->tpc, ppWritePackedMsg, end) && + push8(value->downlink_assignment_index_length, ppWritePackedMsg, end) && + push8(value->downlink_assignment_index, ppWritePackedMsg, end) && + push8(value->allocate_prach_flag, ppWritePackedMsg, end) && + push8(value->preamble_index, ppWritePackedMsg, end) && + push8(value->prach_mask_index, ppWritePackedMsg, end) && + push8(value->starting_ce_level, ppWritePackedMsg, end) && + push8(value->srs_request, ppWritePackedMsg, end) && + push8(value->antenna_ports_and_scrambling_identity_flag, ppWritePackedMsg, end) && + push8(value->antenna_ports_and_scrambling_identity, ppWritePackedMsg, end) && + push8(value->frequency_hopping_enabled_flag, ppWritePackedMsg, end) && + push8(value->paging_direct_indication_differentiation_flag, ppWritePackedMsg, end) && + push8(value->direct_indication, ppWritePackedMsg, end) && + push8(value->total_dci_length_including_padding, ppWritePackedMsg, end) && + push8(value->number_of_tx_antenna_ports, ppWritePackedMsg, end) && + pusharray16(value->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, value->number_of_tx_antenna_ports, ppWritePackedMsg, end)); +} + + +static uint8_t pack_dl_config_nbch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_nbch_pdu_rel13_t* value = (nfapi_dl_config_nbch_pdu_rel13_t*)tlv; + + return (push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push16(value->transmission_power, ppWritePackedMsg, end) && + push16(value->hyper_sfn_2_lsbs, ppWritePackedMsg, end)); +} + + +static uint8_t pack_dl_config_npdcch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_npdcch_pdu_rel13_t* value = (nfapi_dl_config_npdcch_pdu_rel13_t*)tlv; + + return (push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push8(value->ncce_index, ppWritePackedMsg, end) && + push8(value->aggregation_level, ppWritePackedMsg, end) && + push8(value->start_symbol, ppWritePackedMsg, end) && + push8(value->rnti_type, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push8(value->scrambling_reinitialization_batch_index, ppWritePackedMsg, end) && + push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end) && + push8(value->dci_format, ppWritePackedMsg, end) && + push8(value->scheduling_delay, ppWritePackedMsg, end) && + push8(value->resource_assignment, ppWritePackedMsg, end) && + push8(value->repetition_number, ppWritePackedMsg, end) && + push8(value->mcs, ppWritePackedMsg, end) && + push8(value->new_data_indicator, ppWritePackedMsg, end) && + push8(value->harq_ack_resource, ppWritePackedMsg, end) && + push8(value->npdcch_order_indication, ppWritePackedMsg, end) && + push8(value->starting_number_of_nprach_repetitions, ppWritePackedMsg, end) && + push8(value->subcarrier_indication_of_nprach, ppWritePackedMsg, end) && + push8(value->paging_direct_indication_differentation_flag, ppWritePackedMsg, end) && + push8(value->direct_indication, ppWritePackedMsg, end) && + push8(value->dci_subframe_repetition_number, ppWritePackedMsg, end) && + push8(value->total_dci_length_including_padding, ppWritePackedMsg, end)); +} + +static uint8_t pack_dl_config_ndlsch_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_ndlsch_pdu_rel13_t* value = (nfapi_dl_config_ndlsch_pdu_rel13_t*)tlv; + + return (push16(value->length, ppWritePackedMsg, end) && + push16(value->pdu_index, ppWritePackedMsg, end) && + push8(value->start_symbol, ppWritePackedMsg, end) && + push8(value->rnti_type, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) && + push16(value->resource_assignment, ppWritePackedMsg, end) && + push16(value->repetition_number, ppWritePackedMsg, end) && + push8(value->modulation, ppWritePackedMsg, end) && + push8(value->number_of_subframes_for_resource_assignment, ppWritePackedMsg, end) && + push8(value->scrambling_sequence_initialization_cinit, ppWritePackedMsg, end) && + push16(value->sf_idx, ppWritePackedMsg, end) && + push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end)); +} + + +static uint8_t pack_dl_tti_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_request_pdu_t* value = (nfapi_nr_dl_tti_request_pdu_t*)tlv; + + if(!(push16(value->PDUSize, ppWritePackedMsg, end) && + push16(value->PDUType, ppWritePackedMsg, end) )) + return 0; + + + // first match the pdu type, then call the respective function + switch(value->PDUType) + { + case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: + { + if(!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppWritePackedMsg,end))) + return 0; + } + break; + + case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: + { + if(!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppWritePackedMsg,end))) + return 0; + } + break; + case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: + { + if(!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppWritePackedMsg,end))) + return 0; + } + break; + case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: + { + if(!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppWritePackedMsg,end))) + return 0; + } + break; + + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType ); + } + break; + } + + return 1; +} + +static uint8_t pack_dl_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv; + + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() dci:%u pdu:%u pdsch:%u rnti:%u pcfich:%u\n", __FUNCTION__, value->number_dci, value->number_pdu, value->number_pdsch_rnti, value->transmission_power_pcfich); + + if(!(push8(value->number_pdcch_ofdm_symbols, ppWritePackedMsg, end) && + push8(value->number_dci, ppWritePackedMsg, end) && + push16(value->number_pdu, ppWritePackedMsg, end) && + push8(value->number_pdsch_rnti, ppWritePackedMsg, end) && + push16(value->transmission_power_pcfich, ppWritePackedMsg, end))) + { + return 0; + } + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_pdu; + for(; i < total_number_of_pdus; ++i) + { + nfapi_dl_config_request_pdu_t* pdu = &(value->dl_config_pdu_list[i]); + + if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) + return 0; + + // Put a 0 size in and then determine the size after the pdu + // has been writen and write the calculated size + uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; + pdu->pdu_size = 0; + if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: + { + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE\n", __FUNCTION__); + + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel11_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel12_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel13_value))) + { + return 0; + } + } + break; + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: + { + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE\n", __FUNCTION__); + + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_bch_pdu_rel8_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_MCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG, &pdu->mch_pdu.mch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_mch_pdu_rel8_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel8_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel9_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel10_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel11_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel12_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dlsch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_PCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG, &pdu->pch_pdu.pch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_pch_pdu_rel8_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG, &pdu->pch_pdu.pch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_pch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_PRS_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG, &pdu->prs_pdu.prs_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_prs_pdu_rel9_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_csi_rs_pdu_rel10_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_csi_rs_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel8, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel8_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel9, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel9_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel10, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel10_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel11, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel11_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel12, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel12_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_dci_dl_pdu_rel13_value) && + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG, &pdu->epdcch_pdu.epdcch_params_rel11, ppWritePackedMsg, end, &pack_dl_config_epdcch_parameters_rel11_value) & + pack_tlv(NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG, &pdu->epdcch_pdu.epdcch_params_rel13, ppWritePackedMsg, end, &pack_dl_config_epdcch_parameters_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG, &pdu->mpdcch_pdu.mpdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_mpdcch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG, &pdu->nbch_pdu.nbch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_nbch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG, &pdu->npdcch_pdu.npdcch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_npdcch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG, &pdu->ndlsch_pdu.ndlsch_pdu_rel13, ppWritePackedMsg, end, &pack_dl_config_ndlsch_pdu_rel13_value))) + return 0; + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + + // add 1 for the pdu_type. The delta will include the pdu_size + pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); + push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); + } + + return 1; +} + + +static uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t*)msg; + + if (!(push16(pNfapiMsg->SFN , ppWritePackedMsg, end) && + push16(pNfapiMsg->Slot , ppWritePackedMsg, end) && + push8(pNfapiMsg->dl_tti_request_body.nGroup , ppWritePackedMsg, end) && + push8(pNfapiMsg->dl_tti_request_body.nPDUs , ppWritePackedMsg, end) && + pusharray8(pNfapiMsg->dl_tti_request_body.nUe ,256,pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end) + //pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end) + )) + return 0; + + int arr[12]; + for(int i=0;idl_tti_request_body.nGroup;i++) + { + for(int j=0;jdl_tti_request_body.nUe[i];j++) + { + arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j]; + } + if(!(pusharrays32(arr,12,pNfapiMsg->dl_tti_request_body.nUe[i],ppWritePackedMsg, end))) + return 0; + } + + for(int i=0;idl_tti_request_body.nPDUs;i++) + { + if(!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i],ppWritePackedMsg,end)) + return 0; + } + +return 1; +} + + +static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t*)msg; + + //return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + //pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value) && + //pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + { + uint8_t x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); + uint8_t y = pack_tlv(NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, ppWritePackedMsg, end, &pack_dl_config_request_body_value); + uint8_t z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + + if (!x || !y || !z) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST x:%u y:%u z:%u \n", __FUNCTION__,x,y,z); + } + + return x && y && z; + } +} + + + + +static uint8_t pack_ul_config_request_ulsch_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t * end) +{ + nfapi_ul_config_ulsch_pdu_rel8_t* ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t*)tlv; + + return( push32(ulsch_pdu_rel8->handle, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel8->size, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel8->rnti, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->resource_block_start, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->modulation_type, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->frequency_hopping_enabled_flag, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->frequency_hopping_bits, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->new_data_indication, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->redundancy_version, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->harq_process_number, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->ul_tx_mode, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->current_tx_nb, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel8->n_srs, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_ulsch_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel10_t* ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t*)tlv; + + return (push8(ulsch_pdu_rel10->resource_allocation_type, ppWritePackedMsg, end) && + push32(ulsch_pdu_rel10->resource_block_coding, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel10->transport_blocks, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel10->transmission_scheme, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel10->number_of_layers, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel10->codebook_index, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel10->disable_sequence_hopping_flag, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_ulsch_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel11_t* ulsch_pdu_rel11 = (nfapi_ul_config_ulsch_pdu_rel11_t*)tlv; + + return (push8(ulsch_pdu_rel11->virtual_cell_id_enabled_flag, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel11->npusch_identity, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel11->dmrs_config_flag, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel11->ndmrs_csh_identity, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_ulsch_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel13_t* ulsch_pdu_rel13 = (nfapi_ul_config_ulsch_pdu_rel13_t*)tlv; + + return (push8(ulsch_pdu_rel13->ue_type, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel13->total_number_of_repetitions, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel13->repetition_number, ppWritePackedMsg, end) && + push16(ulsch_pdu_rel13->initial_transmission_sf_io, ppWritePackedMsg, end) && + push8(ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, ppWritePackedMsg, end)); +} + +//Pack fns for ul_tti PDUS + + +static uint8_t pack_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t* prach_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return( + push16(prach_pdu->phys_cell_id, ppWritePackedMsg, end) && + push8(prach_pdu->num_prach_ocas, ppWritePackedMsg, end) && + push8(prach_pdu->prach_format, ppWritePackedMsg, end) && + push8(prach_pdu->num_ra, ppWritePackedMsg, end) && + push8(prach_pdu->prach_start_symbol, ppWritePackedMsg, end) && + push16(prach_pdu->num_cs, ppWritePackedMsg, end) + // TODO: ignoring beamforming tlv for now + ); + +} + +static uint8_t pack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t* pucch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return( + push16(pucch_pdu->rnti, ppWritePackedMsg, end) && + push32(pucch_pdu->handle, ppWritePackedMsg, end) && + push16(pucch_pdu->bwp_size, ppWritePackedMsg, end) && + push16(pucch_pdu->bwp_start, ppWritePackedMsg, end) && + push8(pucch_pdu->subcarrier_spacing, ppWritePackedMsg, end) && + push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end) && + push8(pucch_pdu->format_type, ppWritePackedMsg, end) && + push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end) && + push16(pucch_pdu->prb_start, ppWritePackedMsg, end) && + push16(pucch_pdu->prb_size, ppWritePackedMsg, end) && + push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end) && + push8(pucch_pdu->nr_of_symbols, ppWritePackedMsg, end) && + push8(pucch_pdu->freq_hop_flag, ppWritePackedMsg, end) && + push16(pucch_pdu->second_hop_prb, ppWritePackedMsg, end) && + push8(pucch_pdu->group_hop_flag, ppWritePackedMsg, end) && + push8(pucch_pdu->sequence_hop_flag, ppWritePackedMsg, end) && + push16(pucch_pdu->hopping_id, ppWritePackedMsg, end) && + push16(pucch_pdu->initial_cyclic_shift, ppWritePackedMsg, end) && + push16(pucch_pdu->data_scrambling_id, ppWritePackedMsg, end) && + push8(pucch_pdu->time_domain_occ_idx, ppWritePackedMsg, end) && + push8(pucch_pdu->pre_dft_occ_idx, ppWritePackedMsg, end) && + push8(pucch_pdu->pre_dft_occ_len, ppWritePackedMsg, end) && + push8(pucch_pdu->add_dmrs_flag, ppWritePackedMsg, end) && + push16(pucch_pdu->dmrs_scrambling_id, ppWritePackedMsg, end) && + push8(pucch_pdu->dmrs_cyclic_shift, ppWritePackedMsg, end) && + push8(pucch_pdu->sr_flag, ppWritePackedMsg, end) && + push8(pucch_pdu->bit_len_harq, ppWritePackedMsg, end) && + push16(pucch_pdu->bit_len_csi_part1, ppWritePackedMsg, end) && + push16(pucch_pdu->bit_len_csi_part2, ppWritePackedMsg, end) + // TODO: ignoring beamforming tlv for now + ); + +} + + +static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t* pusch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + + if (!( + push16(pusch_pdu->pdu_bit_map, ppWritePackedMsg, end) && + push16(pusch_pdu->rnti, ppWritePackedMsg, end) && + push32(pusch_pdu->handle, ppWritePackedMsg, end) && + push16(pusch_pdu->bwp_size, ppWritePackedMsg, end) && + push16(pusch_pdu->bwp_start, ppWritePackedMsg, end) && + push8(pusch_pdu->subcarrier_spacing, ppWritePackedMsg, end) && + push8(pusch_pdu->cyclic_prefix, ppWritePackedMsg, end) && + push16(pusch_pdu->target_code_rate, ppWritePackedMsg, end) && + push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) && + push8(pusch_pdu->mcs_index, ppWritePackedMsg, end) && + push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) && + push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end) && + push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && + push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end) && + push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && + push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end) && + push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end) && + push8(pusch_pdu->scid, ppWritePackedMsg, end) && + push8(pusch_pdu->num_dmrs_cdm_grps_no_data, ppWritePackedMsg, end) && + push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) && + push8(pusch_pdu->resource_alloc, ppWritePackedMsg, end) && + push8(pusch_pdu->resource_alloc,ppWritePackedMsg, end) && + push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) && + push16(pusch_pdu->rb_start, ppWritePackedMsg, end) && + push16(pusch_pdu->rb_size, ppWritePackedMsg, end) && + push8(pusch_pdu->vrb_to_prb_mapping, ppWritePackedMsg, end) && + push8(pusch_pdu->frequency_hopping, ppWritePackedMsg, end) && + push16(pusch_pdu->tx_direct_current_location, ppWritePackedMsg, end) && + push8(pusch_pdu->uplink_frequency_shift_7p5khz, ppWritePackedMsg, end) && + push8(pusch_pdu->start_symbol_index, ppWritePackedMsg, end) && + push8(pusch_pdu->nr_of_symbols, ppWritePackedMsg, end) + // TODO: ignoring beamforming tlv for now + )) + return 0; + + + //Pack Optional Data only included if indicated in pduBitmap + switch(pusch_pdu->pdu_bit_map){ + case PUSCH_PDU_BITMAP_PUSCH_DATA: + { + // pack optional TLVs + return( + push8(pusch_pdu->pusch_data.rv_index, ppWritePackedMsg, end) && + push8(pusch_pdu->pusch_data.harq_process_id, ppWritePackedMsg, end) && + push32(pusch_pdu->pusch_data.tb_size, ppWritePackedMsg, end) && + push16(pusch_pdu->pusch_data.num_cb, ppWritePackedMsg, end) && + pusharray8(pusch_pdu->pusch_data.cb_present_and_position,1,1,ppWritePackedMsg, end) + ); + } + break; + + case PUSCH_PDU_BITMAP_PUSCH_UCI: + { + return( + push16(pusch_pdu->pusch_uci.harq_ack_bit_length, ppWritePackedMsg, end) && + push16(pusch_pdu->pusch_uci.csi_part1_bit_length, ppWritePackedMsg, end) && + push16(pusch_pdu->pusch_uci.csi_part2_bit_length, ppWritePackedMsg, end) && + push8(pusch_pdu->pusch_uci.alpha_scaling, ppWritePackedMsg, end) && + push8(pusch_pdu->pusch_uci.beta_offset_harq_ack, ppWritePackedMsg, end) && + push8(pusch_pdu->pusch_uci.beta_offset_csi1, ppWritePackedMsg, end) && + push8(pusch_pdu->pusch_uci.beta_offset_csi2, ppWritePackedMsg, end) + ); + } + break; + + case PUSCH_PDU_BITMAP_PUSCH_PTRS: + { + return( + push8(pusch_pdu->pusch_ptrs.num_ptrs_ports, ppWritePackedMsg, end) && + push8(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, ppWritePackedMsg, end) && + push16(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, ppWritePackedMsg, end) && + push8(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, ppWritePackedMsg, end) && + push8(pusch_pdu->pusch_ptrs.ptrs_time_density, ppWritePackedMsg, end) && + push8(pusch_pdu->pusch_ptrs.ptrs_freq_density, ppWritePackedMsg, end) && + push8(pusch_pdu->pusch_ptrs.ul_ptrs_power, ppWritePackedMsg, end) + ); + } + break; + + case PUSCH_PDU_BITMAP_DFTS_OFDM: + { + return( + push8(pusch_pdu->dfts_ofdm.low_papr_group_number, ppWritePackedMsg, end) && + push16(pusch_pdu->dfts_ofdm.low_papr_sequence_number, ppWritePackedMsg, end) && + push8(pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, ppWritePackedMsg, end) && + push8(pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, ppWritePackedMsg, end) + ); + } + break; + + default: + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map ); + } + } + + return 1; +} + +static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t* srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return( + push16(srs_pdu->rnti, ppWritePackedMsg, end) && + push32(srs_pdu->handle, ppWritePackedMsg, end) && + push16(srs_pdu->bwp_size, ppWritePackedMsg, end) && + push16(srs_pdu->bwp_start, ppWritePackedMsg, end) && + push8(srs_pdu->subcarrier_spacing, ppWritePackedMsg, end) && + push8(srs_pdu->cyclic_prefix, ppWritePackedMsg, end) && + push8(srs_pdu->num_ant_ports, ppWritePackedMsg, end) && + push8(srs_pdu->num_symbols, ppWritePackedMsg, end) && + push8(srs_pdu->num_repetitions, ppWritePackedMsg, end) && + push8(srs_pdu->time_start_position, ppWritePackedMsg, end) && + push8(srs_pdu->config_index, ppWritePackedMsg, end) && + push16(srs_pdu->sequence_id, ppWritePackedMsg, end) && + push8(srs_pdu->bandwidth_index, ppWritePackedMsg, end) && + push8(srs_pdu->comb_size, ppWritePackedMsg, end) && + push8(srs_pdu->comb_offset, ppWritePackedMsg, end) && + push8(srs_pdu->cyclic_shift, ppWritePackedMsg, end) && + push8(srs_pdu->frequency_position, ppWritePackedMsg, end) && + push8(srs_pdu->frequency_shift, ppWritePackedMsg, end) && + push8(srs_pdu->frequency_hopping, ppWritePackedMsg, end) && + push8(srs_pdu->group_or_sequence_hopping, ppWritePackedMsg, end) && + push8(srs_pdu->resource_type, ppWritePackedMsg, end) && + push16(srs_pdu->t_srs, ppWritePackedMsg, end) && + push16(srs_pdu->t_offset, ppWritePackedMsg, end) + + // TODO: ignoring beamforming tlv for now + ); + +} + +static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu* ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &ulsch_pdu->ulsch_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &ulsch_pdu->ulsch_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel10_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG, &ulsch_pdu->ulsch_pdu_rel11, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel11_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG, &ulsch_pdu->ulsch_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel13_value)); +} + +static uint8_t pack_ul_config_request_cqi_ri_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel8_t* cqi_ri_info_rel8 = (nfapi_ul_config_cqi_ri_information_rel8_t*)tlv; + + return ( push8(cqi_ri_info_rel8->dl_cqi_pmi_size_rank_1, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel8->dl_cqi_pmi_size_rank_greater_1, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel8->ri_size, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel8->delta_offset_cqi, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel8->delta_offset_ri, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_cqi_ri_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel9_t* cqi_ri_info_rel9 = (nfapi_ul_config_cqi_ri_information_rel9_t*)tlv; + + if(!(push8(cqi_ri_info_rel9->report_type, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel9->delta_offset_cqi, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel9->delta_offset_ri, ppWritePackedMsg, end))) + { + return 0; + } + + switch(cqi_ri_info_rel9->report_type) + { + case NFAPI_CSI_REPORT_TYPE_PERIODIC: + { + if(!(push8(cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size, ppWritePackedMsg, end) && + push8(cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.control_type, ppWritePackedMsg, end))) + { + return 0; + } + } + break; + case NFAPI_CSI_REPORT_TYPE_APERIODIC: + { + if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc, ppWritePackedMsg, end) == 0) + return 0; + + uint8_t i; + for(i = 0; i < cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc; ++i) + { + if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, ppWritePackedMsg, end) == 0) + return 0; + + uint8_t j; + for(j = 0; j < 8; ++j) + { + if(push8(cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], ppWritePackedMsg, end) == 0) + return 0; + } + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel9->report_type ); + } + break; + }; + + return 1; +} + +static uint8_t pack_ul_config_request_cqi_ri_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel13_t* cqi_ri_info_rel13 = (nfapi_ul_config_cqi_ri_information_rel13_t*)tlv; + + switch(cqi_ri_info_rel13->report_type) + { + case NFAPI_CSI_REPORT_TYPE_PERIODIC: + { + if(push16(cqi_ri_info_rel13->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2, ppWritePackedMsg, end) == 0) + return 0; + } + break; + case NFAPI_CSI_REPORT_TYPE_APERIODIC: + { + // No parameters + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel13->report_type ); + } + break; + }; + + return 1; +} + +static uint8_t pack_ul_config_request_cqi_ri_information(nfapi_ul_config_cqi_ri_information* cqi_ri_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return (pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG, &cqi_ri_info->cqi_ri_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG, &cqi_ri_info->cqi_ri_information_rel9, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel9_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG, &cqi_ri_info->cqi_ri_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_cqi_ri_rel13_value)); + +} + +static uint8_t pack_ul_config_request_init_tx_params_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_initial_transmission_parameters_rel8_t* init_tx_params_rel8 = (nfapi_ul_config_initial_transmission_parameters_rel8_t*)tlv; + + return (push8(init_tx_params_rel8->n_srs_initial, ppWritePackedMsg, end) && + push8(init_tx_params_rel8->initial_number_of_resource_blocks, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_initial_transmission_parameters(nfapi_ul_config_initial_transmission_parameters* init_tx_params, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return pack_tlv(NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG, &init_tx_params->initial_transmission_parameters_rel8, ppWritePackedMsg, end, &pack_ul_config_request_init_tx_params_rel8_value); +} + +static uint8_t pack_ul_config_request_ulsch_harq_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_harq_information_rel10_t* harq_info_rel10 = (nfapi_ul_config_ulsch_harq_information_rel10_t*)tlv; + + return (push8(harq_info_rel10->harq_size, ppWritePackedMsg, end) && + push8(harq_info_rel10->delta_offset_harq, ppWritePackedMsg, end) && + push8(harq_info_rel10->ack_nack_mode, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_ulsch_harq_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_ulsch_harq_information_rel13_t*)tlv; + + return (push16(harq_info_rel13->harq_size_2, ppWritePackedMsg, end) && + push8(harq_info_rel13->delta_offset_harq_2, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_ulsch_harq_information(nfapi_ul_config_ulsch_harq_information* harq_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG, &harq_info->harq_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_harq_info_rel10_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG, &harq_info->harq_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_harq_info_rel13_value)); +} + +static uint8_t pack_ul_config_request_ue_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel8_t* ue_info_rel8 = (nfapi_ul_config_ue_information_rel8_t*)tlv; + + return ( push32(ue_info_rel8->handle, ppWritePackedMsg, end) && + push16(ue_info_rel8->rnti, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_ue_info_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel11_t* ue_info_rel11 = (nfapi_ul_config_ue_information_rel11_t*)tlv; + + return ( push8(ue_info_rel11->virtual_cell_id_enabled_flag, ppWritePackedMsg, end) && + push16(ue_info_rel11->npusch_identity, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_ue_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel13_t* ue_info_rel13 = (nfapi_ul_config_ue_information_rel13_t*)tlv; + + return ( push8(ue_info_rel13->ue_type, ppWritePackedMsg, end) && + push8(ue_info_rel13->empty_symbols, ppWritePackedMsg, end) && + push16(ue_info_rel13->total_number_of_repetitions, ppWritePackedMsg, end) && + push16(ue_info_rel13->repetition_number, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_ue_information(nfapi_ul_config_ue_information* ue_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &ue_info->ue_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &ue_info->ue_information_rel11, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel11_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &ue_info->ue_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_ue_info_rel13_value)); +} + +static uint8_t pack_ul_config_request_harq_info_rel10_tdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel10_tdd_t* harq_info_rel10_tdd = (nfapi_ul_config_harq_information_rel10_tdd_t*)tlv; + + return ( push8(harq_info_rel10_tdd->harq_size, ppWritePackedMsg, end) && + push8(harq_info_rel10_tdd->ack_nack_mode, ppWritePackedMsg, end) && + push8(harq_info_rel10_tdd->number_of_pucch_resources, ppWritePackedMsg, end) && + push16(harq_info_rel10_tdd->n_pucch_1_0, ppWritePackedMsg, end) && + push16(harq_info_rel10_tdd->n_pucch_1_1, ppWritePackedMsg, end) && + push16(harq_info_rel10_tdd->n_pucch_1_2, ppWritePackedMsg, end) && + push16(harq_info_rel10_tdd->n_pucch_1_3, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_harq_info_rel8_fdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel8_fdd_t* harq_info_rel8_fdd = (nfapi_ul_config_harq_information_rel8_fdd_t*)tlv; + + return ( push16(harq_info_rel8_fdd->n_pucch_1_0, ppWritePackedMsg, end) && + push8(harq_info_rel8_fdd->harq_size, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_harq_info_rel9_fdd_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel9_fdd_t* harq_info_rel9_fdd = (nfapi_ul_config_harq_information_rel9_fdd_t*)tlv; + + return ( push8(harq_info_rel9_fdd->harq_size, ppWritePackedMsg, end) && + push8(harq_info_rel9_fdd->ack_nack_mode, ppWritePackedMsg, end) && + push8(harq_info_rel9_fdd->number_of_pucch_resources, ppWritePackedMsg, end) && + push16(harq_info_rel9_fdd->n_pucch_1_0, ppWritePackedMsg, end) && + push16(harq_info_rel9_fdd->n_pucch_1_1, ppWritePackedMsg, end) && + push16(harq_info_rel9_fdd->n_pucch_1_2, ppWritePackedMsg, end) && + push16(harq_info_rel9_fdd->n_pucch_1_3, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_harq_info_rel11_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel11_t* harq_info_rel11 = (nfapi_ul_config_harq_information_rel11_t*)tlv; + + return ( push8(harq_info_rel11->num_ant_ports, ppWritePackedMsg, end) && + push16(harq_info_rel11->n_pucch_2_0, ppWritePackedMsg, end) && + push16(harq_info_rel11->n_pucch_2_1, ppWritePackedMsg, end) && + push16(harq_info_rel11->n_pucch_2_2, ppWritePackedMsg, end) && + push16(harq_info_rel11->n_pucch_2_3, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_harq_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_harq_information_rel13_t*)tlv; + + return ( push16(harq_info_rel13->harq_size_2, ppWritePackedMsg, end) && + push8(harq_info_rel13->starting_prb, ppWritePackedMsg, end) && + push8(harq_info_rel13->n_prb, ppWritePackedMsg, end) && + push8(harq_info_rel13->cdm_index, ppWritePackedMsg, end) && + push8(harq_info_rel13->n_srs, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_harq_information(nfapi_ul_config_harq_information* harq_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG, &harq_info->harq_information_rel10_tdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel10_tdd_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG, &harq_info->harq_information_rel8_fdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel8_fdd_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG, &harq_info->harq_information_rel9_fdd, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel9_fdd_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG, &harq_info->harq_information_rel11, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel11_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG, &harq_info->harq_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_harq_info_rel13_value)); + +} + +static uint8_t pack_ul_config_request_cqi_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel8_t* cqi_info_rel8 = (nfapi_ul_config_cqi_information_rel8_t*)tlv; + + return ( push16(cqi_info_rel8->pucch_index, ppWritePackedMsg, end) && + push8(cqi_info_rel8->dl_cqi_pmi_size, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_cqi_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel10_t* cqi_info_rel10 = (nfapi_ul_config_cqi_information_rel10_t*)tlv; + + return ( push8(cqi_info_rel10->number_of_pucch_resource, ppWritePackedMsg, end) && + push16(cqi_info_rel10->pucch_index_p1, ppWritePackedMsg, end)); +} +static uint8_t pack_ul_config_request_cqi_info_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel13_t* cqi_info_rel13 = (nfapi_ul_config_cqi_information_rel13_t*)tlv; + + return ( push8(cqi_info_rel13->csi_mode, ppWritePackedMsg, end) && + push16(cqi_info_rel13->dl_cqi_pmi_size_2, ppWritePackedMsg, end) && + push8(cqi_info_rel13->starting_prb, ppWritePackedMsg, end) && + push8(cqi_info_rel13->n_prb, ppWritePackedMsg, end) && + push8(cqi_info_rel13->cdm_index, ppWritePackedMsg, end) && + push8(cqi_info_rel13->n_srs, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_cqi_information(nfapi_ul_config_cqi_information* cqi_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG, &cqi_info->cqi_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG, &cqi_info->cqi_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel10_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG, &cqi_info->cqi_information_rel13, ppWritePackedMsg, end, &pack_ul_config_request_cqi_info_rel13_value)); + +} + +static uint8_t pack_ul_config_request_sr_info_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_sr_information_rel8_t* sr_info_rel8 = (nfapi_ul_config_sr_information_rel8_t*)tlv; + return push16(sr_info_rel8->pucch_index, ppWritePackedMsg, end); +} +static uint8_t pack_ul_config_request_sr_info_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_sr_information_rel10_t* sr_info_rel10 = (nfapi_ul_config_sr_information_rel10_t*)tlv; + + return ( push8(sr_info_rel10->number_of_pucch_resources, ppWritePackedMsg, end) && + push16(sr_info_rel10->pucch_index_p1, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_sr_information(nfapi_ul_config_sr_information* sr_info, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG, &sr_info->sr_information_rel8, ppWritePackedMsg, end, &pack_ul_config_request_sr_info_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG, &sr_info->sr_information_rel10, ppWritePackedMsg, end, &pack_ul_config_request_sr_info_rel10_value)); +} + +static uint8_t pack_ul_config_request_srs_pdu_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel8_t* srs_pdu_rel8 = (nfapi_ul_config_srs_pdu_rel8_t*)tlv; + + return (push32(srs_pdu_rel8->handle, ppWritePackedMsg, end) && + push16(srs_pdu_rel8->size, ppWritePackedMsg, end) && + push16(srs_pdu_rel8->rnti, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->srs_bandwidth, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->frequency_domain_position, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->srs_hopping_bandwidth, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->transmission_comb, ppWritePackedMsg, end) && + push16(srs_pdu_rel8->i_srs, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->sounding_reference_cyclic_shift, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_srs_pdu_rel10_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel10_t* srs_pdu_rel10 = (nfapi_ul_config_srs_pdu_rel10_t*)tlv; + return push8(srs_pdu_rel10->antenna_port, ppWritePackedMsg, end); +} + +static uint8_t pack_ul_config_request_srs_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel13_t* srs_pdu_rel13 = (nfapi_ul_config_srs_pdu_rel13_t*)tlv; + + return ( push8(srs_pdu_rel13->number_of_combs, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_nb_harq_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_nb_harq_information_rel13_fdd_t* nb_harq_pdu_rel13 = (nfapi_ul_config_nb_harq_information_rel13_fdd_t*)tlv; + + return ( push8(nb_harq_pdu_rel13->harq_ack_resource, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_config_request_nulsch_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_nulsch_pdu_rel13_t* nulsch_pdu_rel13 = (nfapi_ul_config_nulsch_pdu_rel13_t*)tlv; + + return (push8(nulsch_pdu_rel13->nulsch_format, ppWritePackedMsg, end) && + push32(nulsch_pdu_rel13->handle, ppWritePackedMsg, end) && + push16(nulsch_pdu_rel13->size, ppWritePackedMsg, end) && + push16(nulsch_pdu_rel13->rnti, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->subcarrier_indication, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->resource_assignment, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->mcs, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->redudancy_version, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->repetition_number, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->new_data_indication, ppWritePackedMsg, end) && + push8(nulsch_pdu_rel13->n_srs, ppWritePackedMsg, end) && + push16(nulsch_pdu_rel13->scrambling_sequence_initialization_cinit, ppWritePackedMsg, end) && + push16(nulsch_pdu_rel13->sf_idx, ppWritePackedMsg, end) && + pack_ul_config_request_ue_information(&(nulsch_pdu_rel13->ue_information), ppWritePackedMsg, end) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG, &nulsch_pdu_rel13->nb_harq_information.nb_harq_information_rel13_fdd, ppWritePackedMsg, end, &pack_ul_config_request_nb_harq_rel13_value)); +} +static uint8_t pack_ul_config_request_nrach_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_nrach_pdu_rel13_t* nrach_pdu_rel13 = (nfapi_ul_config_nrach_pdu_rel13_t*)tlv; + + return ( push8(nrach_pdu_rel13->nprach_config_0, ppWritePackedMsg, end) && + push8(nrach_pdu_rel13->nprach_config_1, ppWritePackedMsg, end) && + push8(nrach_pdu_rel13->nprach_config_2, ppWritePackedMsg, end)); + +} + + + +static uint8_t pack_ul_tti_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_ul_tti_request_number_of_pdus_t* value = (nfapi_nr_ul_tti_request_number_of_pdus_t*)tlv; + + if(!(push16(value->pdu_size, ppWritePackedMsg, end) && + push16(value->pdu_type, ppWritePackedMsg, end) )) + return 0; + + + // first match the pdu type, then call the respective function + switch(value->pdu_type) + { + case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: + { + if(!pack_ul_tti_request_prach_pdu(&value->prach_pdu, ppWritePackedMsg, end)) + return 0; + } + break; + + case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: + { + if(!pack_ul_tti_request_pucch_pdu(&value->pucch_pdu, ppWritePackedMsg, end)) + return 0; + } + break; + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + { + if(!pack_ul_tti_request_pusch_pdu(&value->pusch_pdu, ppWritePackedMsg, end)) + return 0; + } + break; + case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: + { + if(!pack_ul_tti_request_srs_pdu(&value->srs_pdu, ppWritePackedMsg, end)) + return 0; + } + break; + + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", value->pdu_type ); + } + break; + } + + return 1; +} + +static uint8_t pack_ul_tti_groups_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_ul_tti_request_number_of_groups_t* value = (nfapi_nr_ul_tti_request_number_of_groups_t*)tlv; + + if(!push8(value->n_ue, ppWritePackedMsg, end)) + return 0; + for(int i=0; in_ue;i++) + { + if(!push8(value->ue_list[i].pdu_idx, ppWritePackedMsg, end)) + return 0; + } + return 1; +} + +static uint8_t pack_ul_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_config_request_body_t* value = (nfapi_ul_config_request_body_t*)tlv; + + if(!(push8(value->number_of_pdus, ppWritePackedMsg, end) && + push8(value->rach_prach_frequency_resources, ppWritePackedMsg, end) && + push8(value->srs_present, ppWritePackedMsg, end))) + return 0; + + uint16_t i = 0; + for(i = 0; i < value->number_of_pdus; ++i) + { + nfapi_ul_config_request_pdu_t* pdu = &(value->ul_config_pdu_list[i]); + + if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) + return 0; + + // Put a 0 size in and then determine the size after the pdu + // has been writen and write the calculated size + uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; + pdu->pdu_size = 0; + if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: + { + if(!pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_pdu), ppWritePackedMsg, end)) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_cqi_ri_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_ri_information(&(pdu->ulsch_cqi_ri_pdu.cqi_ri_information), ppWritePackedMsg, end) && + pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_cqi_ri_pdu.initial_transmission_parameters), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_ulsch_harq_information(&(pdu->ulsch_harq_pdu.harq_information), ppWritePackedMsg, end) && + pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_harq_pdu.initial_transmission_parameters), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_ri_information(&(pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information), ppWritePackedMsg, end) && + pack_ul_config_request_ulsch_harq_information(&(pdu->ulsch_cqi_harq_ri_pdu.harq_information), ppWritePackedMsg, end) && + pack_ul_config_request_initial_transmission_parameters(&(pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->uci_cqi_pdu.cqi_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_sr_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_sr_information(&(pdu->uci_sr_pdu.sr_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_harq_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->uci_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_sr_harq_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_sr_information(&(pdu->uci_sr_harq_pdu.sr_information), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->uci_sr_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_harq_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->uci_cqi_harq_pdu.cqi_information), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->uci_cqi_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_sr_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->uci_cqi_sr_pdu.cqi_information), ppWritePackedMsg, end) && + pack_ul_config_request_sr_information(&(pdu->uci_cqi_sr_pdu.sr_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->uci_cqi_sr_harq_pdu.ue_information), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->uci_cqi_sr_harq_pdu.cqi_information), ppWritePackedMsg, end) && + pack_ul_config_request_sr_information(&(pdu->uci_cqi_sr_harq_pdu.sr_information), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->uci_cqi_sr_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_SRS_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG, &pdu->srs_pdu.srs_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel8_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG, &pdu->srs_pdu.srs_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel10_value) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG, &pdu->srs_pdu.srs_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_srs_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: + { + if(!(pack_ul_config_request_ue_information(&(pdu->harq_buffer_pdu.ue_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_uci_csi_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->ulsch_uci_csi_pdu.csi_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_uci_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->ulsch_uci_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: + { + if(!(pack_ul_config_request_ulsch_pdu(&(pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu), ppWritePackedMsg, end) && + pack_ul_config_request_cqi_information(&(pdu->ulsch_csi_uci_harq_pdu.csi_information), ppWritePackedMsg, end) && + pack_ul_config_request_harq_information(&(pdu->ulsch_csi_uci_harq_pdu.harq_information), ppWritePackedMsg, end))) + return 0; + } + break; + case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG, &pdu->nulsch_pdu.nulsch_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_nulsch_pdu_rel13_value))) + return 0; + } + break; + case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG, &pdu->nrach_pdu.nrach_pdu_rel13, ppWritePackedMsg, end, &pack_ul_config_request_nrach_pdu_rel13_value))) + return 0; + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + + // add 1 for the pdu_type. The delta will include the pdu_size + pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); + push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); + + } + return 1; +} + + +static uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t*)msg; + + if (!(push16(pNfapiMsg->SFN , ppWritePackedMsg, end) && + push16(pNfapiMsg->Slot , ppWritePackedMsg, end) && + push8(pNfapiMsg->n_pdus , ppWritePackedMsg, end) && + push8(pNfapiMsg->rach_present, ppWritePackedMsg, end) && + push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end) && + push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end) && + push8(pNfapiMsg->n_group, ppWritePackedMsg, end) )) + return 0; + + for(int i=0; in_pdus; i++) + { + if(!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end)) + return 0; + } + + for(int i=0; in_group; i++) + { + if(!pack_ul_tti_groups_list_value(&pNfapiMsg->groups_list[i], ppWritePackedMsg, end)) + return 0; + + } + + return 1; +} + + +static uint8_t pack_ul_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_UL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->ul_config_request_body, ppWritePackedMsg, end, &pack_ul_config_request_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)) ; +} + +static uint8_t pack_hi_dci0_hi_rel8_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_hi_pdu_rel8_t* hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t*)tlv; + + return ( push8(hi_pdu_rel8->resource_block_start, ppWritePackedMsg, end) && + push8(hi_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) && + push8(hi_pdu_rel8->hi_value, ppWritePackedMsg, end) && + push8(hi_pdu_rel8->i_phich, ppWritePackedMsg, end) && + push16(hi_pdu_rel8->transmission_power, ppWritePackedMsg, end)); +} + +static uint8_t pack_hi_dci0_hi_rel10_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_hi_pdu_rel10_t* hi_pdu_rel10 = (nfapi_hi_dci0_hi_pdu_rel10_t*)tlv; + + return ( push8(hi_pdu_rel10->flag_tb2, ppWritePackedMsg, end) && + push8(hi_pdu_rel10->hi_value_2, ppWritePackedMsg, end)); +} + +static uint8_t pack_hi_dci0_dci_rel8_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel8_t* dci_pdu_rel8 = (nfapi_hi_dci0_dci_pdu_rel8_t*)tlv; + + return ( push8(dci_pdu_rel8->dci_format, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->cce_index, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->aggregation_level, ppWritePackedMsg, end) && + push16(dci_pdu_rel8->rnti, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->resource_block_start, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->number_of_resource_block, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->mcs_1, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->cyclic_shift_2_for_drms, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->frequency_hopping_enabled_flag, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->frequency_hopping_bits, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->new_data_indication_1, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->ue_tx_antenna_seleciton, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->tpc, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->cqi_csi_request, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->ul_index, ppWritePackedMsg, end) && + push8(dci_pdu_rel8->dl_assignment_index, ppWritePackedMsg, end) && + push32(dci_pdu_rel8->tpc_bitmap, ppWritePackedMsg, end) && + push16(dci_pdu_rel8->transmission_power, ppWritePackedMsg, end)); +} + +static uint8_t pack_hi_dci0_dci_rel10_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel10_t* dci_pdu_rel10 = (nfapi_hi_dci0_dci_pdu_rel10_t*)tlv; + + return ( push8(dci_pdu_rel10->cross_carrier_scheduling_flag, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->carrier_indicator, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->size_of_cqi_csi_feild, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->srs_flag, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->srs_request, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->resource_allocation_flag, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->resource_allocation_type, ppWritePackedMsg, end) && + push32(dci_pdu_rel10->resource_block_coding, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->mcs_2, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->new_data_indication_2, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->number_of_antenna_ports, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->tpmi, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->total_dci_length_including_padding, ppWritePackedMsg, end) && + push8(dci_pdu_rel10->n_ul_rb, ppWritePackedMsg, end)); +} + +static uint8_t pack_hi_dci0_dci_rel12_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel12_t* dci_pdu_rel12 = (nfapi_hi_dci0_dci_pdu_rel12_t*)tlv; + + return ( push8(dci_pdu_rel12->pscch_resource, ppWritePackedMsg, end) && + push8(dci_pdu_rel12->time_resource_pattern, ppWritePackedMsg, end)); +} + +static uint8_t pack_hi_dci0_mpdcch_dci_rel13_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t* mpdcch_dci_pdu_rel13 = (nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t*)tlv; + + return ( push8(mpdcch_dci_pdu_rel13->mpdcch_narrowband, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->number_of_prb_pairs, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->resource_block_assignment, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->mpdcch_transmission_type, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->start_symbol, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->ecce_index, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->aggreagation_level, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->rnti_type, ppWritePackedMsg, end) && + push16(mpdcch_dci_pdu_rel13->rnti, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->ce_mode, ppWritePackedMsg, end) && + push16(mpdcch_dci_pdu_rel13->drms_scrambling_init, ppWritePackedMsg, end) && + push16(mpdcch_dci_pdu_rel13->initial_transmission_sf_io, ppWritePackedMsg, end) && + push16(mpdcch_dci_pdu_rel13->transmission_power, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->dci_format, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->resource_block_start, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->number_of_resource_blocks, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->mcs, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->pusch_repetition_levels, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->frequency_hopping_flag, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->new_data_indication, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->harq_process, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->redudency_version, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->tpc, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->csi_request, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->ul_inex, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->dai_presence_flag, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->dl_assignment_index, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->srs_request, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->dci_subframe_repetition_number, ppWritePackedMsg, end) && + push32(mpdcch_dci_pdu_rel13->tcp_bitmap, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->total_dci_length_include_padding, ppWritePackedMsg, end) && + push8(mpdcch_dci_pdu_rel13->number_of_tx_antenna_ports, ppWritePackedMsg, end) && + pusharray16(mpdcch_dci_pdu_rel13->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, mpdcch_dci_pdu_rel13->number_of_tx_antenna_ports, ppWritePackedMsg, end)); + +} + +static uint8_t pack_hi_dci0_npdcch_dci_rel13_pdu_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_npdcch_dci_pdu_rel13_t* npdcch_dci_pdu_rel13 = (nfapi_hi_dci0_npdcch_dci_pdu_rel13_t*)tlv; + + return ( push8(npdcch_dci_pdu_rel13->ncce_index, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->aggregation_level, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->start_symbol, ppWritePackedMsg, end) && + push16(npdcch_dci_pdu_rel13->rnti, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->scrambling_reinitialization_batch_index, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->subcarrier_indication, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->resource_assignment, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->scheduling_delay, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->mcs, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->redudancy_version, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->repetition_number, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->new_data_indicator, ppWritePackedMsg, end) && + push8(npdcch_dci_pdu_rel13->dci_subframe_repetition_number, ppWritePackedMsg, end)); +} + + +static uint8_t pack_hi_dci0_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_request_body_t* value = (nfapi_hi_dci0_request_body_t*)tlv; + + if(!(push16(value->sfnsf, ppWritePackedMsg, end) && + push8(value->number_of_dci, ppWritePackedMsg, end) && + push8(value->number_of_hi, ppWritePackedMsg, end))) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_dci + value->number_of_hi; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_hi_dci0_request_pdu_t* pdu = &(value->hi_dci0_pdu_list[i]); + + if(push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) + return 0; + + // Put a 0 size in and then determine the size after the pdu + // has been writen and write the calculated size + uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; + pdu->pdu_size = 0; + if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_HI_DCI0_HI_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG, &pdu->hi_pdu.hi_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_hi_rel8_pdu_value) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG, &pdu->hi_pdu.hi_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_hi_rel10_pdu_value))) + return 0; + } + break; + case NFAPI_HI_DCI0_DCI_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG, &pdu->dci_pdu.dci_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_dci_rel8_pdu_value) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG, &pdu->dci_pdu.dci_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_dci_rel10_pdu_value) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG, &pdu->dci_pdu.dci_pdu_rel12, ppWritePackedMsg, end, pack_hi_dci0_dci_rel12_pdu_value))) + return 0; + } + break; + case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel8, ppWritePackedMsg, end, pack_hi_dci0_dci_rel8_pdu_value) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel10, ppWritePackedMsg, end, pack_hi_dci0_dci_rel10_pdu_value) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG, &pdu->epdcch_dci_pdu.epdcch_parameters_rel11, ppWritePackedMsg, end, pack_dl_config_epdcch_parameters_rel11_value))) + return 0; + } + break; + case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG, &pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13, ppWritePackedMsg, end, pack_hi_dci0_mpdcch_dci_rel13_pdu_value))) + return 0; + } + break; + case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: + { + if(!(pack_tlv(NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG, &pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13, ppWritePackedMsg, end, pack_hi_dci0_npdcch_dci_rel13_pdu_value))) + return 0; + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + + // add 1 for the pdu_type. The delta will include the pdu_size + pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); + push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); + + } + + return 1; +} + +static uint8_t pack_ul_dci_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_ul_dci_request_pdus_t* value = (nfapi_nr_ul_dci_request_pdus_t*)tlv; + + for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) + { + if(!push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, ppWritePackedMsg, end) && + push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, ppWritePackedMsg, end) && + + push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) && + push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, ppWritePackedMsg, end) && + push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, ppWritePackedMsg, end) && + push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) && + + push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) && + push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) && + + pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end)); + + return 0; + } + + return (push16(value->PDUType, ppWritePackedMsg, end) && + push16(value->PDUSize, ppWritePackedMsg, end) && + push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, ppWritePackedMsg, end) && + push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, ppWritePackedMsg, end) && + push8(value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, ppWritePackedMsg, end) && + push8(value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, ppWritePackedMsg, end) && + + push8(value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, ppWritePackedMsg, end) && + push8(value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, ppWritePackedMsg, end) && + pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, ppWritePackedMsg, end) && + push8(value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, ppWritePackedMsg, end) && + + push8(value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, ppWritePackedMsg, end) && + push8(value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, ppWritePackedMsg, end) && + push8(value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, ppWritePackedMsg, end) && + push16(value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, ppWritePackedMsg, end)); + +} + +static uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t*)msg; + + if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && + push16(pNfapiMsg->Slot, ppWritePackedMsg, end) && + push8(pNfapiMsg->numPdus, ppWritePackedMsg, end) + )) + return 0; + + for(int i=0; inumPdus; i++) + { + if(!pack_ul_dci_pdu_list_value(&pNfapiMsg->ul_dci_pdu_list[i], ppWritePackedMsg, end)) + return 0; + } + return 1; + + +} + + + +static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_HI_DCI0_REQUEST_BODY_TAG, &pNfapiMsg->hi_dci0_request_body, ppWritePackedMsg, end, &pack_hi_dci0_request_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +//pack_tx_data_pdu_list_value +static uint8_t pack_tx_data_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nr_pdu_t* value = (nfapi_nr_pdu_t*)tlv; + + if(!(push32(value->num_TLV, ppWritePackedMsg, end) && + push16(value->PDU_index, ppWritePackedMsg, end) && + push16(value->PDU_length, ppWritePackedMsg, end) + )) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_tlvs = value->num_TLV; + for(; i < total_number_of_tlvs; ++i) + { + + if (!(push16(value->TLVs[i].length, ppWritePackedMsg, end) && + push16(value->TLVs[i].tag, ppWritePackedMsg, end))) + return 0; + + switch(value->TLVs[i].tag) + { + case 0: + { + if(!pusharray32(value->TLVs[i].value.direct, 16384, value->TLVs[i].length, ppWritePackedMsg, end)) + return 0; + break; + + } + + case 1: + { + if(!pusharray32(value->TLVs[i].value.ptr, value->TLVs[i].length , value->TLVs[i].length, ppWritePackedMsg, end)) + return 0; + break; + + } + + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", value->TLVs[i].tag ); + break; + } + + } + } + return 1; +} + +static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_tx_request_body_t* value = (nfapi_tx_request_body_t*)tlv; + + if(push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(; i < total_number_of_pdus; ++i) + { + nfapi_tx_request_pdu_t* pdu = &(value->tx_pdu_list[i]); + + if(!(push16(pdu->pdu_length, ppWritePackedMsg, end) && + push16(pdu->pdu_index, ppWritePackedMsg, end))) + return 0; + + uint8_t j; + for(j = 0; j < pdu->num_segments; ++j) + { + // Use -1 as it is unbounded + // DJP - does not handle -1 + // DJP - if(pusharray8(pdu->segments[j].segment_data, (uint32_t)(-1), pdu->segments[j].segment_length, ppWritePackedMsg, end) == 0) + int push_ret = pusharray8(pdu->segments[j].segment_data, 65535, pdu->segments[j].segment_length, ppWritePackedMsg, end); + if (pdu->segments[j].segment_length == 3) - { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, - pdu->segments[j].segment_data[0], - pdu->segments[j].segment_data[1], - pdu->segments[j].segment_data[2] - ); - } - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() segment_data:%p segment_length:%u pusharray8()=%d\n", __FUNCTION__, pdu->segments[j].segment_data, pdu->segments[j].segment_length, push_ret); - - if (push_ret == 0) - { - return 0; - } - } - } - - return 1; -} - -static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t*)msg; - - int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); - int y = pack_tlv(NFAPI_TX_REQUEST_BODY_TAG, &pNfapiMsg->tx_request_body, ppWritePackedMsg, end, &pack_tx_request_body_value); - int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); - - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() x:%d y:%d z:%d\n", __FUNCTION__, x, y, z); - - return x && y && z; -} + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, + pdu->segments[j].segment_data[0], + pdu->segments[j].segment_data[1], + pdu->segments[j].segment_data[2] + ); + } + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() segment_data:%p segment_length:%u pusharray8()=%d\n", __FUNCTION__, pdu->segments[j].segment_data, pdu->segments[j].segment_length, push_ret); + + if (push_ret == 0) + { + return 0; + } + } + } + + return 1; +} + +static uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t*)msg; + + if (!( + push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && + push16(pNfapiMsg->Slot, ppWritePackedMsg, end) && + push16(pNfapiMsg->Number_of_PDUs, ppWritePackedMsg, end) + )) + return 0; + + for(int i=0; iNumber_of_PDUs; i++) + { + if(!pack_tx_data_pdu_list_value(&pNfapiMsg->pdu_list[i], ppWritePackedMsg, end)) + return 0; + } + + return 1; +} + +static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t*)msg; + + int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); + int y = pack_tlv(NFAPI_TX_REQUEST_BODY_TAG, &pNfapiMsg->tx_request_body, ppWritePackedMsg, end, &pack_tx_request_body_value); + int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() x:%d y:%d z:%d\n", __FUNCTION__, x, y, z); + + return x && y && z; +} static uint8_t pack_release_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { @@ -1620,1094 +2274,1138 @@ static uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, u return x && z; } -static uint8_t pack_rx_ue_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv; - - return ( push32(value->handle, ppWritePackedMsg, end) && - push16(value->rnti, ppWritePackedMsg, end) ); -} - -static uint8_t unpack_rx_ue_information_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv; - - return ( pull32(ppReadPackedMsg, &value->handle, end) && - pull16(ppReadPackedMsg, &value->rnti, end)); -} - -static uint8_t pack_harq_indication_tdd_harq_data_bundling(nfapi_harq_indication_tdd_harq_data_bundling_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( push8(data->value_0, ppWritePackedMsg, end) && - push8(data->value_1, ppWritePackedMsg, end)); -} - -static uint8_t pack_harq_indication_tdd_harq_data_multiplexing(nfapi_harq_indication_tdd_harq_data_multiplexing_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( push8(data->value_0, ppWritePackedMsg, end) && - push8(data->value_1, ppWritePackedMsg, end) && - push8(data->value_2, ppWritePackedMsg, end) && - push8(data->value_3, ppWritePackedMsg, end)); -} - -static uint8_t pack_harq_indication_tdd_harq_data_special_bundling(nfapi_harq_indication_tdd_harq_data_special_bundling_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( push8(data->value_0, ppWritePackedMsg, end) ); -} - -static uint8_t pack_harq_indication_tdd_harq_data(nfapi_harq_indication_tdd_harq_data_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - return ( push8(data->value_0, ppWritePackedMsg, end) ); -} - -static uint8_t pack_harq_indication_tdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_harq_indication_tdd_rel8_t* harq_indication_tdd_rel8 = (nfapi_harq_indication_tdd_rel8_t*)tlv; - - if(!(push8(harq_indication_tdd_rel8->mode, ppWritePackedMsg, end) && - push8(harq_indication_tdd_rel8->number_of_ack_nack, ppWritePackedMsg, end))) - return 0; - - uint8_t result = 0; - switch(harq_indication_tdd_rel8->mode) - { - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: - result = pack_harq_indication_tdd_harq_data_bundling(&harq_indication_tdd_rel8->harq_data.bundling, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: - result = pack_harq_indication_tdd_harq_data_multiplexing(&harq_indication_tdd_rel8->harq_data.multiplex, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: - result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel8->harq_data.special_bundling, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: - result = 1; - break; - default: - // err.... - break; - } - - return result; - -} - -static uint8_t pack_harq_indication_tdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_harq_indication_tdd_rel9_t* harq_indication_tdd_rel9 = (nfapi_harq_indication_tdd_rel9_t*)tlv; - - if(!(push8(harq_indication_tdd_rel9->mode, ppWritePackedMsg, end) && - push8(harq_indication_tdd_rel9->number_of_ack_nack, ppWritePackedMsg, end))) - return 0; - - uint8_t idx; - for(idx = 0; idx < harq_indication_tdd_rel9->number_of_ack_nack; ++idx) - { - uint8_t result = 0; - - switch(harq_indication_tdd_rel9->mode) - { - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: - result = pack_harq_indication_tdd_harq_data(&(harq_indication_tdd_rel9->harq_data[idx].bundling), ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: - result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].multiplex, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: - result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel9->harq_data[idx].special_bundling, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: - result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].channel_selection, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: - result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].format_3, ppWritePackedMsg, end); - break; - default: - // err.... - break; - } - - if(result == 0) - return 0; - } - - return 1; -} - -static uint8_t pack_harq_indication_tdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_harq_indication_tdd_rel13_t* harq_indication_tdd_rel13 = (nfapi_harq_indication_tdd_rel13_t*)tlv; - - if(!(push8(harq_indication_tdd_rel13->mode, ppWritePackedMsg, end) && - push16(harq_indication_tdd_rel13->number_of_ack_nack, ppWritePackedMsg, end))) - return 0; - - uint8_t idx; - for(idx = 0; idx < harq_indication_tdd_rel13->number_of_ack_nack; ++idx) - { - uint8_t result = 0; - switch(harq_indication_tdd_rel13->mode) - { - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: - result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].bundling, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: - result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].multiplex, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: - result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel13->harq_data[idx].special_bundling, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: - result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].channel_selection, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: - result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_3, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_4: - result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_4, ppWritePackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_5: - result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_5, ppWritePackedMsg, end); - break; - default: - // err.... - break; - } - - if(result == 0) - return 0; - } - - return 1; -} - -static uint8_t pack_harq_indication_fdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_harq_indication_fdd_rel8_t* harq_indication_fdd_rel8 = (nfapi_harq_indication_fdd_rel8_t*)tlv; - - return ( push8(harq_indication_fdd_rel8->harq_tb1, ppWritePackedMsg, end) && - push8(harq_indication_fdd_rel8->harq_tb2, ppWritePackedMsg, end)); -} - -static uint8_t pack_harq_indication_fdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_harq_indication_fdd_rel9_t* harq_indication_fdd_rel9 = (nfapi_harq_indication_fdd_rel9_t*)tlv; - - return ( push8(harq_indication_fdd_rel9->mode, ppWritePackedMsg, end) && - push8(harq_indication_fdd_rel9->number_of_ack_nack, ppWritePackedMsg, end) && - pusharray8(harq_indication_fdd_rel9->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL9_MAX, harq_indication_fdd_rel9->number_of_ack_nack, ppWritePackedMsg, end)); -} - -static uint8_t pack_harq_indication_fdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_harq_indication_fdd_rel13_t* harq_indication_fdd_rel13 = (nfapi_harq_indication_fdd_rel13_t*)tlv; - - return ( push8(harq_indication_fdd_rel13->mode, ppWritePackedMsg, end) && - push16(harq_indication_fdd_rel13->number_of_ack_nack, ppWritePackedMsg, end) && - pusharray8(harq_indication_fdd_rel13->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL13_MAX, harq_indication_fdd_rel13->number_of_ack_nack, ppWritePackedMsg, end)); -} - -static uint8_t pack_ul_cqi_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ul_cqi_information_t* value = (nfapi_ul_cqi_information_t*)tlv; - - return ( push8(value->ul_cqi, ppWritePackedMsg, end) && - push8(value->channel, ppWritePackedMsg, end)); - -} - -static uint8_t pack_harq_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_harq_indication_body_t* value = (nfapi_harq_indication_body_t*)tlv; - - if(push16(value->number_of_harqs, ppWritePackedMsg, end) == 0) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_pdus = value->number_of_harqs; - for(; i < total_number_of_pdus; ++i) - { - nfapi_harq_indication_pdu_t* pdu = &(value->harq_pdu_list[i]); - - uint8_t* instance_length_p = *ppWritePackedMsg; - if(!push16(pdu->instance_length, ppWritePackedMsg, end)) - return 0; - - if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && - pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL8_TAG, &pdu->harq_indication_tdd_rel8, ppWritePackedMsg, end, pack_harq_indication_tdd_rel8_value) && - pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL9_TAG, &pdu->harq_indication_tdd_rel9, ppWritePackedMsg, end, pack_harq_indication_tdd_rel9_value) && - pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL13_TAG, &pdu->harq_indication_tdd_rel13, ppWritePackedMsg, end, pack_harq_indication_tdd_rel13_value) && - pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL8_TAG, &pdu->harq_indication_fdd_rel8, ppWritePackedMsg, end, pack_harq_indication_fdd_rel8_value) && - pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL9_TAG, &pdu->harq_indication_fdd_rel9, ppWritePackedMsg, end, pack_harq_indication_fdd_rel9_value) && - pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL13_TAG, &pdu->harq_indication_fdd_rel13, ppWritePackedMsg, end, pack_harq_indication_fdd_rel13_value) && - pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) - return 0; - - // calculate the instance length subtracting the size of the instance - // length feild - uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; - push16(instance_length, &instance_length_p, end); - } - - return 1; -} - -static uint8_t pack_harq_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_harq_indication_t *pNfapiMsg = (nfapi_harq_indication_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->harq_indication_body, ppWritePackedMsg, end, pack_harq_indication_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - -static uint8_t pack_crc_indication_rel8_body(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_crc_indication_rel8_t* crc_indication_rel8 = (nfapi_crc_indication_rel8_t*)tlv; - - return ( push8(crc_indication_rel8->crc_flag, ppWritePackedMsg, end) ); -} - -static uint8_t pack_crc_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_crc_indication_body_t* value = (nfapi_crc_indication_body_t*)tlv; - - if(push16(value->number_of_crcs, ppWritePackedMsg, end) == 0) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_pdus = value->number_of_crcs; - for(; i < total_number_of_pdus; ++i) - { - nfapi_crc_indication_pdu_t* pdu = &(value->crc_pdu_list[i]); - - uint8_t* instance_length_p = *ppWritePackedMsg; - if(!push16(pdu->instance_length, ppWritePackedMsg, end)) - return 0; - - if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && - pack_tlv(NFAPI_CRC_INDICATION_REL8_TAG, &pdu->crc_indication_rel8, ppWritePackedMsg, end, pack_crc_indication_rel8_body))) - return 0; - - // calculate the instance length subtracting the size of the instance - // length feild - uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; - push16(instance_length, &instance_length_p, end); - } - return 1; -} - -static uint8_t pack_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_crc_indication_t *pNfapiMsg = (nfapi_crc_indication_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_CRC_INDICATION_BODY_TAG, &pNfapiMsg->crc_indication_body, ppWritePackedMsg, end, &pack_crc_indication_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); - -} -static uint8_t pack_rx_indication_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_rx_indication_rel8_t* value = (nfapi_rx_indication_rel8_t*)tlv; - - return ( push16(value->length, ppWritePackedMsg, end) && - push16(value->offset, ppWritePackedMsg, end) && - push8(value->ul_cqi, ppWritePackedMsg, end) && - push16(value->timing_advance, ppWritePackedMsg, end)); -} -static uint8_t pack_rx_indication_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_rx_indication_rel9_t* value = (nfapi_rx_indication_rel9_t*)tlv; - - return ( push16(value->timing_advance_r9, ppWritePackedMsg, end)); -} - -static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_rx_indication_body_t* value = (nfapi_rx_indication_body_t*)tlv; - - //printf("RX ULSCH BODY\n"); - - if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) - return 0; - - // need to calculate the data offset's. - uint16_t i = 0; - uint16_t offset = 2; // taking into account the number_of_pdus - uint16_t total_number_of_pdus = value->number_of_pdus; - //printf("ULSCH:pdus:%d\n", total_number_of_pdus); - - for(i = 0; i < total_number_of_pdus; ++i) - { - nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); - if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG) - { - //printf("NFAPI_RX_UE_INFORMATION_TAG\n"); - offset += 4 + 6; - } - - if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) - { - //printf("NFAPI_RX_INDICATION_REL8_TAG\n"); - offset += 4 + 7; - } - - if(pdu->rx_indication_rel9.tl.tag == NFAPI_RX_INDICATION_REL9_TAG) - { - //printf("NFAPI_RX_INDICATION_REL9_TAG\n"); - offset += 4 + 2; - } - } - - // Now update the structure to include the offset - for(i =0; i < total_number_of_pdus; ++i) - { - nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); - - if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) - { - if(pdu->rx_indication_rel8.offset == 1) - { - pdu->rx_indication_rel8.offset = offset; - offset += pdu->rx_indication_rel8.length; - } - } - } - - // Write out the pdu - for(i = 0; i < total_number_of_pdus; ++i) - { - nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); - if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && - pack_tlv(NFAPI_RX_INDICATION_REL8_TAG, &pdu->rx_indication_rel8, ppWritePackedMsg, end, pack_rx_indication_rel8_value) && - pack_tlv(NFAPI_RX_INDICATION_REL9_TAG, &pdu->rx_indication_rel9, ppWritePackedMsg, end, pack_rx_indication_rel9_value))) - return 0; - } - - // Write out the pdu data - for(i = 0; i < total_number_of_pdus; ++i) - { - uint16_t length = 0; - nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); - - if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) - { - length = pdu->rx_indication_rel8.length; - } - - if( pusharray8(value->rx_pdu_list[i].data, length, length, ppWritePackedMsg, end) == 0) - return 0; - } - return 1; -} - - -static uint8_t pack_rx_ulsch_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_rx_indication_t *pNfapiMsg = (nfapi_rx_indication_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_RX_INDICATION_BODY_TAG, &pNfapiMsg->rx_indication_body, ppWritePackedMsg, end, pack_rx_ulsch_indication_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - -static uint8_t pack_preamble_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_preamble_pdu_rel8_t* preamble_rel8 = (nfapi_preamble_pdu_rel8_t*)tlv; - - return ( push16(preamble_rel8->rnti, ppWritePackedMsg, end) && - push8(preamble_rel8->preamble, ppWritePackedMsg, end) && - push16(preamble_rel8->timing_advance, ppWritePackedMsg, end)); -} -static uint8_t pack_preamble_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_preamble_pdu_rel9_t* preamble_rel9 = (nfapi_preamble_pdu_rel9_t*)tlv; - - return ( push16(preamble_rel9->timing_advance_r9, ppWritePackedMsg, end) ); -} -static uint8_t pack_preamble_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_preamble_pdu_rel13_t* preamble_rel13 = (nfapi_preamble_pdu_rel13_t*)tlv; - - return ( push8(preamble_rel13->rach_resource_type, ppWritePackedMsg, end) ); -} - -static uint8_t pack_rach_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_rach_indication_body_t* value = (nfapi_rach_indication_body_t*)tlv; - - if( push16(value->number_of_preambles, ppWritePackedMsg, end) == 0) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_pdus = value->number_of_preambles; - for(; i < total_number_of_pdus; ++i) - { - nfapi_preamble_pdu_t* pdu = &(value->preamble_list[i]); - - uint8_t* instance_length_p = *ppWritePackedMsg; - if(!push16(pdu->instance_length, ppWritePackedMsg, end)) - return 0; - - if(!(pack_tlv(NFAPI_PREAMBLE_REL8_TAG, &pdu->preamble_rel8, ppWritePackedMsg, end, pack_preamble_pdu_rel8_value) && - pack_tlv(NFAPI_PREAMBLE_REL9_TAG, &pdu->preamble_rel9, ppWritePackedMsg, end, pack_preamble_pdu_rel9_value) && - pack_tlv(NFAPI_PREAMBLE_REL13_TAG, &pdu->preamble_rel13, ppWritePackedMsg, end, pack_preamble_pdu_rel13_value))) - return 0; - - // calculate the instance length subtracting the size of the instance - // length feild - uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; - push16(instance_length, &instance_length_p, end); - } - - return 1; -} - -static uint8_t pack_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_rach_indication_t *pNfapiMsg = (nfapi_rach_indication_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_RACH_INDICATION_BODY_TAG, &pNfapiMsg->rach_indication_body, ppWritePackedMsg, end, pack_rach_indication_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - -static uint8_t pack_srs_indication_fdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_srs_indication_fdd_rel8_t* srs_pdu_rel8 = (nfapi_srs_indication_fdd_rel8_t*)tlv; - - return ( push16(srs_pdu_rel8->doppler_estimation, ppWritePackedMsg, end) && - push16(srs_pdu_rel8->timing_advance, ppWritePackedMsg, end) && - push8(srs_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end) && - push8(srs_pdu_rel8->rb_start, ppWritePackedMsg, end) && - pusharray8(srs_pdu_rel8->snr, NFAPI_NUM_RB_MAX, srs_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end)); -} - -static uint8_t pack_srs_indication_fdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_srs_indication_fdd_rel9_t* srs_pdu_rel9 = (nfapi_srs_indication_fdd_rel9_t*)tlv; - - return ( push16(srs_pdu_rel9->timing_advance_r9, ppWritePackedMsg, end) ); -} - -static uint8_t pack_srs_indication_tdd_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_srs_indication_ttd_rel10_t* srs_pdu_rel10 = (nfapi_srs_indication_ttd_rel10_t*)tlv; - - return ( push8(srs_pdu_rel10->uppts_symbol, ppWritePackedMsg, end) ); - -} - -static uint8_t pack_srs_indication_fdd_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_srs_indication_fdd_rel11_t* srs_pdu_rel11 = (nfapi_srs_indication_fdd_rel11_t*)tlv; - - return ( push16(srs_pdu_rel11->ul_rtoa, ppWritePackedMsg, end) ) ; -} - -static uint8_t pack_tdd_channel_measurement_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_tdd_channel_measurement_t* value = (nfapi_tdd_channel_measurement_t*)tlv; - - if(!(push8(value->num_prb_per_subband, ppWritePackedMsg, end) && - push8(value->number_of_subbands, ppWritePackedMsg, end) && - push8(value->num_atennas, ppWritePackedMsg, end))) - return 0; - - uint8_t idx = 0; - for(idx = 0; idx < value->number_of_subbands; ++idx) - { - if(!(push8(value->subands[idx].subband_index, ppWritePackedMsg, end) && - pusharray16(value->subands[idx].channel, NFAPI_MAX_NUM_PHYSICAL_ANTENNAS, value->num_atennas, ppWritePackedMsg, end))) - return 0; - } - - return 1; -} - -static uint8_t pack_srs_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_srs_indication_body_t *value = (nfapi_srs_indication_body_t*)tlv; - - if( push8(value->number_of_ues, ppWritePackedMsg, end) == 0) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_pdus = value->number_of_ues; - for(; i < total_number_of_pdus; ++i) - { - nfapi_srs_indication_pdu_t* pdu = &(value->srs_pdu_list[i]); - - uint8_t* instance_length_p = *ppWritePackedMsg; - if(!push16(pdu->instance_length, ppWritePackedMsg, end)) - return 0; - - if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, &pack_rx_ue_information_value) && - pack_tlv(NFAPI_SRS_INDICATION_FDD_REL8_TAG, &pdu->srs_indication_fdd_rel8, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel8_value) && - pack_tlv(NFAPI_SRS_INDICATION_FDD_REL9_TAG, &pdu->srs_indication_fdd_rel9, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel9_value) && - pack_tlv(NFAPI_SRS_INDICATION_TDD_REL10_TAG, &pdu->srs_indication_tdd_rel10, ppWritePackedMsg, end, &pack_srs_indication_tdd_rel10_value) && - pack_tlv(NFAPI_SRS_INDICATION_FDD_REL11_TAG, &pdu->srs_indication_fdd_rel11, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel11_value) && - pack_tlv(NFAPI_TDD_CHANNEL_MEASUREMENT_TAG, &pdu->tdd_channel_measurement, ppWritePackedMsg, end, &pack_tdd_channel_measurement_value))) - return 0; - - // calculate the instance length subtracting the size of the instance - // length feild - uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; - push16(instance_length, &instance_length_p, end); - } - - return 1; -} - -static uint8_t pack_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_srs_indication_t *pNfapiMsg = (nfapi_srs_indication_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_SRS_INDICATION_BODY_TAG, &pNfapiMsg->srs_indication_body, ppWritePackedMsg, end, &pack_srs_indication_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); - -} - -static uint8_t pack_sr_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_sr_indication_body_t* value = (nfapi_sr_indication_body_t*)tlv; - - if(push16(value->number_of_srs, ppWritePackedMsg, end) == 0) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_pdus = value->number_of_srs; - for(; i < total_number_of_pdus; ++i) - { - nfapi_sr_indication_pdu_t* pdu = &(value->sr_pdu_list[i]); - - uint8_t* instance_length_p = *ppWritePackedMsg; - if(!push16(pdu->instance_length, ppWritePackedMsg, end)) - return 0; - - if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && - pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) - return 0; - - // calculate the instance length subtracting the size of the instance - // length feild - uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; - push16(instance_length, &instance_length_p, end); - } - return 1; -} - -static uint8_t pack_sr_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_sr_indication_t *pNfapiMsg = (nfapi_sr_indication_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_SR_INDICATION_BODY_TAG, &pNfapiMsg->sr_indication_body, ppWritePackedMsg, end, &pack_sr_indication_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); - -} - -static uint8_t pack_cqi_indication_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_cqi_indication_rel8_t* cqi_pdu_rel8 = (nfapi_cqi_indication_rel8_t*)tlv; - - return ( push16(cqi_pdu_rel8->length, ppWritePackedMsg, end) && - push16(cqi_pdu_rel8->data_offset, ppWritePackedMsg, end) && - push8(cqi_pdu_rel8->ul_cqi, ppWritePackedMsg, end) && - push8(cqi_pdu_rel8->ri, ppWritePackedMsg, end) && - push16(cqi_pdu_rel8->timing_advance, ppWritePackedMsg, end)); -} - -static uint8_t pack_cqi_indication_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_cqi_indication_rel9_t* cqi_pdu_rel9 = (nfapi_cqi_indication_rel9_t*)tlv; - - return ( push16(cqi_pdu_rel9->length, ppWritePackedMsg, end) && - push16(cqi_pdu_rel9->data_offset, ppWritePackedMsg, end) && - push8(cqi_pdu_rel9->ul_cqi, ppWritePackedMsg, end) && - push8(cqi_pdu_rel9->number_of_cc_reported, ppWritePackedMsg, end) && - pusharray8(cqi_pdu_rel9->ri, NFAPI_CC_MAX, cqi_pdu_rel9->number_of_cc_reported, ppWritePackedMsg, end) && - push16(cqi_pdu_rel9->timing_advance, ppWritePackedMsg, end) && - push16(cqi_pdu_rel9->timing_advance_r9, ppWritePackedMsg, end)); -} - -static uint8_t pack_cqi_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_cqi_indication_body_t* value = (nfapi_cqi_indication_body_t*)tlv; - - if( push16(value->number_of_cqis, ppWritePackedMsg, end) == 0) - return 0; - - // need to calculate the data offset's. This very bittle due the hardcoding - // of the sizes. can not use the sizeof as we have an array for the Rel9 - // info - uint16_t i = 0; - uint16_t offset = 2; // taking into account the number_of_cqis - uint16_t total_number_of_pdus = value->number_of_cqis; - for(i = 0; i < total_number_of_pdus; ++i) - { - nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); - - offset += 2; // for the instance length - - if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG) - { - offset += 4 + 6; // sizeof(nfapi_rx_ue_information) - sizeof(nfapi_tl_t) - } - - if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) - { - offset += 4 + 8; - } - - if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) - { - offset += 4 + 10 + pdu->cqi_indication_rel9.number_of_cc_reported; - } - - if(pdu->ul_cqi_information.tl.tag == NFAPI_UL_CQI_INFORMATION_TAG) - { - offset += 4 + 2; - } - } - - // Now update the structure to include the offset - for(i =0; i < total_number_of_pdus; ++i) - { - nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); - - if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) - { - if(pdu->cqi_indication_rel8.data_offset == 1) - { - pdu->cqi_indication_rel8.data_offset = offset; - offset += pdu->cqi_indication_rel8.length; - } - } - - if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) - { - if(pdu->cqi_indication_rel9.data_offset == 1) - { - pdu->cqi_indication_rel9.data_offset = offset; - offset += pdu->cqi_indication_rel9.length; - } - } - - } - - // Write out the cqi information - for(i = 0; i < total_number_of_pdus; ++i) - { - nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); - - uint8_t* instance_length_p = *ppWritePackedMsg; - if(!push16(pdu->instance_length, ppWritePackedMsg, end)) - return 0; - - if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end ,pack_rx_ue_information_value) && - pack_tlv(NFAPI_CQI_INDICATION_REL8_TAG, &pdu->cqi_indication_rel8, ppWritePackedMsg, end, pack_cqi_indication_rel8_value) && - pack_tlv(NFAPI_CQI_INDICATION_REL9_TAG, &pdu->cqi_indication_rel9, ppWritePackedMsg, end, pack_cqi_indication_rel9_value) && - pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) - return 0; - - // calculate the instance length subtracting the size of the instance - // length feild - uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; - push16(instance_length, &instance_length_p, end); - - } - - // Write out the cqi raw data - for(i = 0; i < total_number_of_pdus; ++i) - { - uint16_t length = 0; - nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); - - if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) - { - length = pdu->cqi_indication_rel8.length; - } - - if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) - { - length = pdu->cqi_indication_rel9.length; - } - - if( pusharray8(value->cqi_raw_pdu_list[i].pdu, NFAPI_CQI_RAW_MAX_LEN, length, ppWritePackedMsg, end) == 0) - return 0; - } - - return 1; -} - -static uint8_t pack_cqi_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_cqi_indication_t *pNfapiMsg = (nfapi_cqi_indication_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_CQI_INDICATION_BODY_TAG, &pNfapiMsg->cqi_indication_body, ppWritePackedMsg, end, pack_cqi_indication_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); - -} - -static uint8_t pack_lbt_pdsch_req_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_lbt_pdsch_req_pdu_rel13_t* value = (nfapi_lbt_pdsch_req_pdu_rel13_t*)tlv; - - return ( push32(value->handle, ppWritePackedMsg, end) && - push32(value->mp_cca, ppWritePackedMsg, end) && - push32(value->n_cca, ppWritePackedMsg, end) && - push32(value->offset, ppWritePackedMsg, end) && - push32(value->lte_txop_sf, ppWritePackedMsg, end) && - push16(value->txop_sfn_sf_end, ppWritePackedMsg, end) && - push32(value->lbt_mode, ppWritePackedMsg, end)); -} - -static uint8_t pack_lbt_drs_req_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_lbt_drs_req_pdu_rel13_t* value = (nfapi_lbt_drs_req_pdu_rel13_t*)tlv; - - return ( push32(value->handle, ppWritePackedMsg, end) && - push32(value->offset, ppWritePackedMsg, end) && - push16(value->sfn_sf_end, ppWritePackedMsg, end) && - push32(value->lbt_mode, ppWritePackedMsg, end)); -} - -static uint8_t pack_lbt_dl_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_lbt_dl_config_request_body_t* value = (nfapi_lbt_dl_config_request_body_t*)tlv; - - if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_pdus = value->number_of_pdus; - for(; i < total_number_of_pdus; ++i) - { - nfapi_lbt_dl_config_request_pdu_t* pdu = &(value->lbt_dl_config_req_pdu_list[i]); - - if( push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) - return 0; - - // Put a 0 size in and then determine the size after the pdu - // has been writen and write the calculated size - uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; - pdu->pdu_size = 0; - if( push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) - return 0; - - switch(pdu->pdu_type) - { - case NFAPI_LBT_DL_CONFIG_REQUEST_PDSCH_PDU_TYPE: - { - if( pack_tlv(NFAPI_LBT_PDSCH_REQ_PDU_REL13_TAG, &pdu->lbt_pdsch_req_pdu.lbt_pdsch_req_pdu_rel13, ppWritePackedMsg, end, pack_lbt_pdsch_req_pdu_rel13_value) == 0) - return 0; - } - break; - case NFAPI_LBT_DL_CONFIG_REQUEST_DRS_PDU_TYPE: - { - if(pack_tlv(NFAPI_LBT_DRS_REQ_PDU_REL13_TAG, &pdu->lbt_drs_req_pdu.lbt_drs_req_pdu_rel13, ppWritePackedMsg, end, pack_lbt_drs_req_pdu_rel13_value) == 0) - return 0; - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL_CONFIG.request invalid pdu type %d \n", pdu->pdu_type ); - } - break; - }; - - // add 1 for the pdu_type. The delta will include the pdu_size - pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); - push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); - } - - return 1; -} - -static uint8_t pack_lbt_pdsch_rsp_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_lbt_pdsch_rsp_pdu_rel13_t* value = (nfapi_lbt_pdsch_rsp_pdu_rel13_t*)tlv; - - return ( push32(value->handle, ppWritePackedMsg, end) && - push32(value->result, ppWritePackedMsg, end) && - push32(value->lte_txop_symbols, ppWritePackedMsg, end) && - push32(value->initial_partial_sf, ppWritePackedMsg, end)); -} - -static uint8_t pack_lbt_drs_rsp_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_lbt_drs_rsp_pdu_rel13_t* value = (nfapi_lbt_drs_rsp_pdu_rel13_t*)tlv; - - return ( push32(value->handle, ppWritePackedMsg, end) && - push32(value->result, ppWritePackedMsg, end)); -} - -static uint8_t pack_lbt_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_lbt_dl_config_request_t *pNfapiMsg = (nfapi_lbt_dl_config_request_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_LBT_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->lbt_dl_config_request_body, ppWritePackedMsg, end, &pack_lbt_dl_config_request_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - -static uint8_t pack_lbt_dl_config_indication_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_lbt_dl_indication_body_t* value = (nfapi_lbt_dl_indication_body_t*)tlv; - - if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_pdus = value->number_of_pdus; - for(; i < total_number_of_pdus; ++i) - { - nfapi_lbt_dl_indication_pdu_t* pdu = &(value->lbt_indication_pdu_list[i]); - - if( push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) - return 0; - - // Put a 0 size in and then determine the size after the pdu - // has been writen and write the calculated size - uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; - pdu->pdu_size = 0; - - if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) - return 0; - - switch(pdu->pdu_type) - { - case NFAPI_LBT_DL_RSP_PDSCH_PDU_TYPE: - { - if( pack_tlv(NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG, &pdu->lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13, ppWritePackedMsg, end, pack_lbt_pdsch_rsp_pdu_rel13_value) == 0) - return 0; - } - break; - case NFAPI_LBT_DL_RSP_DRS_PDU_TYPE: - { - if( pack_tlv(NFAPI_LBT_DRS_RSP_PDU_REL13_TAG, &pdu->lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13, ppWritePackedMsg, end, pack_lbt_drs_rsp_pdu_rel13_value) == 0) - return 0; - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL.indication body invalid pdu type %d \n", pdu->pdu_type ); - } - break; - }; - - // add 1 for the pdu_type. The delta will include the pdu_size - pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); - push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); - } - - return 1; -} - -static uint8_t pack_lbt_dl_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_lbt_dl_indication_t *pNfapiMsg = (nfapi_lbt_dl_indication_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_LBT_DL_INDICATION_BODY_TAG, &pNfapiMsg->lbt_dl_indication_body, ppWritePackedMsg, end, &pack_lbt_dl_config_indication_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - -static uint8_t pack_nb_harq_indication_fdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_nb_harq_indication_fdd_rel13_t* nb_harq_indication_fdd_rel13 = (nfapi_nb_harq_indication_fdd_rel13_t*)tlv; - - return ( push8(nb_harq_indication_fdd_rel13->harq_tb1, ppWritePackedMsg, end) ); -} - -static uint8_t pack_nb_harq_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_nb_harq_indication_body_t* value = (nfapi_nb_harq_indication_body_t*)tlv; - - if( push16(value->number_of_harqs, ppWritePackedMsg, end) == 0) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_harqs = value->number_of_harqs; - for(; i < total_number_of_harqs; ++i) - { - nfapi_nb_harq_indication_pdu_t* pdu = &(value->nb_harq_pdu_list[i]); - - uint8_t* instance_length_p = *ppWritePackedMsg; - if(!push16(pdu->instance_length, ppWritePackedMsg, end)) - return 0; - - if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && - pack_tlv(NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG, &pdu->nb_harq_indication_fdd_rel13, ppWritePackedMsg, end, pack_nb_harq_indication_fdd_rel13_value) && - pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) - return 0; - - // calculate the instance length subtracting the size of the instance - // length feild - uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; - push16(instance_length, &instance_length_p, end); - } - - return 1; -} - - -static uint8_t pack_nb_harq_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_nb_harq_indication_t *pNfapiMsg = (nfapi_nb_harq_indication_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_NB_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->nb_harq_indication_body, ppWritePackedMsg, end, &pack_nb_harq_indication_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - -static uint8_t pack_nrach_indication_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_nrach_indication_pdu_rel13_t* nrach_indication_fdd_rel13 = (nfapi_nrach_indication_pdu_rel13_t*)tlv; - - return ( push16(nrach_indication_fdd_rel13->rnti, ppWritePackedMsg, end) && - push8(nrach_indication_fdd_rel13->initial_sc, ppWritePackedMsg, end) && - push16(nrach_indication_fdd_rel13->timing_advance, ppWritePackedMsg, end) && - push8(nrach_indication_fdd_rel13->nrach_ce_level, ppWritePackedMsg, end)); -} - - -static uint8_t pack_nrach_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv; - - if( push8(value->number_of_initial_scs_detected, ppWritePackedMsg, end) == 0) - return 0; - - uint16_t i = 0; - uint16_t total_number_of_initial_scs_detected = value->number_of_initial_scs_detected; - for(; i < total_number_of_initial_scs_detected; ++i) - { - nfapi_nrach_indication_pdu_t* pdu = &(value->nrach_pdu_list[i]); - - //uint8_t* instance_length_p = *ppWritePackedMsg; - //if(!push16(pdu->instance_length, ppWritePackedMsg, end)) - // return 0; - - if(!(pack_tlv(NFAPI_NRACH_INDICATION_REL13_TAG, &pdu->nrach_indication_rel13, ppWritePackedMsg, end, pack_nrach_indication_rel13_value))) - return 0; - - // calculate the instance length subtracting the size of the instance - // length feild - //uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; - //push16(instance_length, &instance_length_p, end); - } - - return 1; -} - -static uint8_t pack_nrach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_nrach_indication_t *pNfapiMsg = (nfapi_nrach_indication_t*)msg; - - return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && - pack_tlv(NFAPI_NRACH_INDICATION_BODY_TAG, &pNfapiMsg->nrach_indication_body, ppWritePackedMsg, end, &pack_nrach_indication_body_value) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - -static uint8_t pack_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t*)msg; - - return ( push32(pNfapiMsg->t1, ppWritePackedMsg, end) && - pushs32(pNfapiMsg->delta_sfn_sf, ppWritePackedMsg, end) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - -static uint8_t pack_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t*)msg; - - return (push32(pNfapiMsg->t1, ppWritePackedMsg, end) && - push32(pNfapiMsg->t2, ppWritePackedMsg, end) && - push32(pNfapiMsg->t3, ppWritePackedMsg, end) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - -static uint8_t pack_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t*)msg; - - return (push32(pNfapiMsg->last_sfn_sf, ppWritePackedMsg, end) && - push32(pNfapiMsg->time_since_last_timing_info, ppWritePackedMsg, end) && - push32(pNfapiMsg->dl_config_jitter, ppWritePackedMsg, end) && - push32(pNfapiMsg->tx_request_jitter, ppWritePackedMsg, end) && - push32(pNfapiMsg->ul_config_jitter, ppWritePackedMsg, end) && - push32(pNfapiMsg->hi_dci0_jitter, ppWritePackedMsg, end) && - pushs32(pNfapiMsg->dl_config_latest_delay, ppWritePackedMsg, end) && - pushs32(pNfapiMsg->tx_request_latest_delay, ppWritePackedMsg, end) && - pushs32(pNfapiMsg->ul_config_latest_delay, ppWritePackedMsg, end) && - pushs32(pNfapiMsg->hi_dci0_latest_delay, ppWritePackedMsg, end) && - pushs32(pNfapiMsg->dl_config_earliest_arrival, ppWritePackedMsg, end) && - pushs32(pNfapiMsg->tx_request_earliest_arrival, ppWritePackedMsg, end) && - pushs32(pNfapiMsg->ul_config_earliest_arrival, ppWritePackedMsg, end) && - pushs32(pNfapiMsg->hi_dci0_earliest_arrival, ppWritePackedMsg, end) && - pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); -} - - -// Main pack function - public - -int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config) -{ - nfapi_p7_message_header_t *pMessageHeader = pMessageBuf; - uint8_t *pWritePackedMessage = pPackedBuf; - uint8_t *pPackedLengthField = &pWritePackedMessage[4]; - uint8_t *end = pPackedBuf + packedBufLen; - - if (pMessageBuf == NULL || pPackedBuf == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n"); - return -1; - } - - // process the header - if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && - push16(pMessageHeader->message_id, &pWritePackedMessage, end) && - push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) && - push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end) && - push32(0/*pMessageHeader->checksum*/, &pWritePackedMessage, end) && - push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end))) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n"); - return -1; - } - - if (pMessageHeader->message_id != NFAPI_TIMING_INFO) - { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__, pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp); - } - // look for the specific message - uint8_t result = 0; - switch (pMessageHeader->message_id) - { - case NFAPI_DL_CONFIG_REQUEST: - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST\n", __FUNCTION__); - result = pack_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_UL_CONFIG_REQUEST: - result = pack_ul_config_request(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_HI_DCI0_REQUEST: - result = pack_hi_dci0_request(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_TX_REQUEST: - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__); - result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config); - break; +static uint8_t pack_rx_ue_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv; + + return ( push32(value->handle, ppWritePackedMsg, end) && + push16(value->rnti, ppWritePackedMsg, end) ); +} +static uint8_t unpack_rx_ue_information_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv; + + return ( pull32(ppReadPackedMsg, &value->handle, end) && + pull16(ppReadPackedMsg, &value->rnti, end)); +} + +static uint8_t pack_harq_indication_tdd_harq_data_bundling(nfapi_harq_indication_tdd_harq_data_bundling_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( push8(data->value_0, ppWritePackedMsg, end) && + push8(data->value_1, ppWritePackedMsg, end)); +} + +static uint8_t pack_harq_indication_tdd_harq_data_multiplexing(nfapi_harq_indication_tdd_harq_data_multiplexing_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( push8(data->value_0, ppWritePackedMsg, end) && + push8(data->value_1, ppWritePackedMsg, end) && + push8(data->value_2, ppWritePackedMsg, end) && + push8(data->value_3, ppWritePackedMsg, end)); +} + +static uint8_t pack_harq_indication_tdd_harq_data_special_bundling(nfapi_harq_indication_tdd_harq_data_special_bundling_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( push8(data->value_0, ppWritePackedMsg, end) ); +} + +static uint8_t pack_harq_indication_tdd_harq_data(nfapi_harq_indication_tdd_harq_data_t* data, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + return ( push8(data->value_0, ppWritePackedMsg, end) ); +} + +static uint8_t pack_harq_indication_tdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel8_t* harq_indication_tdd_rel8 = (nfapi_harq_indication_tdd_rel8_t*)tlv; + + if(!(push8(harq_indication_tdd_rel8->mode, ppWritePackedMsg, end) && + push8(harq_indication_tdd_rel8->number_of_ack_nack, ppWritePackedMsg, end))) + return 0; + + uint8_t result = 0; + switch(harq_indication_tdd_rel8->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = pack_harq_indication_tdd_harq_data_bundling(&harq_indication_tdd_rel8->harq_data.bundling, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = pack_harq_indication_tdd_harq_data_multiplexing(&harq_indication_tdd_rel8->harq_data.multiplex, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel8->harq_data.special_bundling, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + result = 1; + break; + default: + // err.... + break; + } + + return result; + +} + +static uint8_t pack_harq_indication_tdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel9_t* harq_indication_tdd_rel9 = (nfapi_harq_indication_tdd_rel9_t*)tlv; + + if(!(push8(harq_indication_tdd_rel9->mode, ppWritePackedMsg, end) && + push8(harq_indication_tdd_rel9->number_of_ack_nack, ppWritePackedMsg, end))) + return 0; + + uint8_t idx; + for(idx = 0; idx < harq_indication_tdd_rel9->number_of_ack_nack; ++idx) + { + uint8_t result = 0; + + switch(harq_indication_tdd_rel9->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = pack_harq_indication_tdd_harq_data(&(harq_indication_tdd_rel9->harq_data[idx].bundling), ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].multiplex, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel9->harq_data[idx].special_bundling, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].channel_selection, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel9->harq_data[idx].format_3, ppWritePackedMsg, end); + break; + default: + // err.... + break; + } + + if(result == 0) + return 0; + } + + return 1; +} + +static uint8_t pack_harq_indication_tdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel13_t* harq_indication_tdd_rel13 = (nfapi_harq_indication_tdd_rel13_t*)tlv; + + if(!(push8(harq_indication_tdd_rel13->mode, ppWritePackedMsg, end) && + push16(harq_indication_tdd_rel13->number_of_ack_nack, ppWritePackedMsg, end))) + return 0; + + uint8_t idx; + for(idx = 0; idx < harq_indication_tdd_rel13->number_of_ack_nack; ++idx) + { + uint8_t result = 0; + switch(harq_indication_tdd_rel13->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].bundling, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].multiplex, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = pack_harq_indication_tdd_harq_data_special_bundling(&harq_indication_tdd_rel13->harq_data[idx].special_bundling, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].channel_selection, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_3, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_4: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_4, ppWritePackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_5: + result = pack_harq_indication_tdd_harq_data(&harq_indication_tdd_rel13->harq_data[idx].format_5, ppWritePackedMsg, end); + break; + default: + // err.... + break; + } + + if(result == 0) + return 0; + } + + return 1; +} + +static uint8_t pack_harq_indication_fdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel8_t* harq_indication_fdd_rel8 = (nfapi_harq_indication_fdd_rel8_t*)tlv; + + return ( push8(harq_indication_fdd_rel8->harq_tb1, ppWritePackedMsg, end) && + push8(harq_indication_fdd_rel8->harq_tb2, ppWritePackedMsg, end)); +} + +static uint8_t pack_harq_indication_fdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel9_t* harq_indication_fdd_rel9 = (nfapi_harq_indication_fdd_rel9_t*)tlv; + + return ( push8(harq_indication_fdd_rel9->mode, ppWritePackedMsg, end) && + push8(harq_indication_fdd_rel9->number_of_ack_nack, ppWritePackedMsg, end) && + pusharray8(harq_indication_fdd_rel9->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL9_MAX, harq_indication_fdd_rel9->number_of_ack_nack, ppWritePackedMsg, end)); +} + +static uint8_t pack_harq_indication_fdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel13_t* harq_indication_fdd_rel13 = (nfapi_harq_indication_fdd_rel13_t*)tlv; + + return ( push8(harq_indication_fdd_rel13->mode, ppWritePackedMsg, end) && + push16(harq_indication_fdd_rel13->number_of_ack_nack, ppWritePackedMsg, end) && + pusharray8(harq_indication_fdd_rel13->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL13_MAX, harq_indication_fdd_rel13->number_of_ack_nack, ppWritePackedMsg, end)); +} + +static uint8_t pack_ul_cqi_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ul_cqi_information_t* value = (nfapi_ul_cqi_information_t*)tlv; + + return ( push8(value->ul_cqi, ppWritePackedMsg, end) && + push8(value->channel, ppWritePackedMsg, end)); + +} + +static uint8_t pack_harq_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_harq_indication_body_t* value = (nfapi_harq_indication_body_t*)tlv; + + if(push16(value->number_of_harqs, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_harqs; + for(; i < total_number_of_pdus; ++i) + { + nfapi_harq_indication_pdu_t* pdu = &(value->harq_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && + pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL8_TAG, &pdu->harq_indication_tdd_rel8, ppWritePackedMsg, end, pack_harq_indication_tdd_rel8_value) && + pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL9_TAG, &pdu->harq_indication_tdd_rel9, ppWritePackedMsg, end, pack_harq_indication_tdd_rel9_value) && + pack_tlv(NFAPI_HARQ_INDICATION_TDD_REL13_TAG, &pdu->harq_indication_tdd_rel13, ppWritePackedMsg, end, pack_harq_indication_tdd_rel13_value) && + pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL8_TAG, &pdu->harq_indication_fdd_rel8, ppWritePackedMsg, end, pack_harq_indication_fdd_rel8_value) && + pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL9_TAG, &pdu->harq_indication_fdd_rel9, ppWritePackedMsg, end, pack_harq_indication_fdd_rel9_value) && + pack_tlv(NFAPI_HARQ_INDICATION_FDD_REL13_TAG, &pdu->harq_indication_fdd_rel13, ppWritePackedMsg, end, pack_harq_indication_fdd_rel13_value) && + pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + + return 1; +} + +static uint8_t pack_harq_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_harq_indication_t *pNfapiMsg = (nfapi_harq_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->harq_indication_body, ppWritePackedMsg, end, pack_harq_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_crc_indication_rel8_body(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_crc_indication_rel8_t* crc_indication_rel8 = (nfapi_crc_indication_rel8_t*)tlv; + + return ( push8(crc_indication_rel8->crc_flag, ppWritePackedMsg, end) ); +} + +static uint8_t pack_crc_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_crc_indication_body_t* value = (nfapi_crc_indication_body_t*)tlv; + + if(push16(value->number_of_crcs, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_crcs; + for(; i < total_number_of_pdus; ++i) + { + nfapi_crc_indication_pdu_t* pdu = &(value->crc_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && + pack_tlv(NFAPI_CRC_INDICATION_REL8_TAG, &pdu->crc_indication_rel8, ppWritePackedMsg, end, pack_crc_indication_rel8_body))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + return 1; +} + +static uint8_t pack_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_crc_indication_t *pNfapiMsg = (nfapi_crc_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_CRC_INDICATION_BODY_TAG, &pNfapiMsg->crc_indication_body, ppWritePackedMsg, end, &pack_crc_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} +static uint8_t pack_rx_indication_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rx_indication_rel8_t* value = (nfapi_rx_indication_rel8_t*)tlv; + + return ( push16(value->length, ppWritePackedMsg, end) && + push16(value->offset, ppWritePackedMsg, end) && + push8(value->ul_cqi, ppWritePackedMsg, end) && + push16(value->timing_advance, ppWritePackedMsg, end)); +} +static uint8_t pack_rx_indication_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rx_indication_rel9_t* value = (nfapi_rx_indication_rel9_t*)tlv; + + return ( push16(value->timing_advance_r9, ppWritePackedMsg, end)); +} + +static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rx_indication_body_t* value = (nfapi_rx_indication_body_t*)tlv; + + //printf("RX ULSCH BODY\n"); + + if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) + return 0; + + // need to calculate the data offset's. + uint16_t i = 0; + uint16_t offset = 2; // taking into account the number_of_pdus + uint16_t total_number_of_pdus = value->number_of_pdus; + //printf("ULSCH:pdus:%d\n", total_number_of_pdus); + + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); + if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG) + { + //printf("NFAPI_RX_UE_INFORMATION_TAG\n"); + offset += 4 + 6; + } + + if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) + { + //printf("NFAPI_RX_INDICATION_REL8_TAG\n"); + offset += 4 + 7; + } + + if(pdu->rx_indication_rel9.tl.tag == NFAPI_RX_INDICATION_REL9_TAG) + { + //printf("NFAPI_RX_INDICATION_REL9_TAG\n"); + offset += 4 + 2; + } + } + + // Now update the structure to include the offset + for(i =0; i < total_number_of_pdus; ++i) + { + nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); + + if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) + { + if(pdu->rx_indication_rel8.offset == 1) + { + pdu->rx_indication_rel8.offset = offset; + offset += pdu->rx_indication_rel8.length; + } + } + } + + // Write out the pdu + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && + pack_tlv(NFAPI_RX_INDICATION_REL8_TAG, &pdu->rx_indication_rel8, ppWritePackedMsg, end, pack_rx_indication_rel8_value) && + pack_tlv(NFAPI_RX_INDICATION_REL9_TAG, &pdu->rx_indication_rel9, ppWritePackedMsg, end, pack_rx_indication_rel9_value))) + return 0; + } + + // Write out the pdu data + for(i = 0; i < total_number_of_pdus; ++i) + { + uint16_t length = 0; + nfapi_rx_indication_pdu_t* pdu = &(value->rx_pdu_list[i]); + + if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) + { + length = pdu->rx_indication_rel8.length; + } + + if( pusharray8(value->rx_pdu_list[i].data, length, length, ppWritePackedMsg, end) == 0) + return 0; + } + return 1; +} + + +static uint8_t pack_rx_ulsch_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_rx_indication_t *pNfapiMsg = (nfapi_rx_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_RX_INDICATION_BODY_TAG, &pNfapiMsg->rx_indication_body, ppWritePackedMsg, end, pack_rx_ulsch_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_preamble_pdu_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel8_t* preamble_rel8 = (nfapi_preamble_pdu_rel8_t*)tlv; + + return ( push16(preamble_rel8->rnti, ppWritePackedMsg, end) && + push8(preamble_rel8->preamble, ppWritePackedMsg, end) && + push16(preamble_rel8->timing_advance, ppWritePackedMsg, end)); +} +static uint8_t pack_preamble_pdu_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel9_t* preamble_rel9 = (nfapi_preamble_pdu_rel9_t*)tlv; + + return ( push16(preamble_rel9->timing_advance_r9, ppWritePackedMsg, end) ); +} +static uint8_t pack_preamble_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel13_t* preamble_rel13 = (nfapi_preamble_pdu_rel13_t*)tlv; + + return ( push8(preamble_rel13->rach_resource_type, ppWritePackedMsg, end) ); +} + +static uint8_t pack_rach_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_rach_indication_body_t* value = (nfapi_rach_indication_body_t*)tlv; + + if( push16(value->number_of_preambles, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_preambles; + for(; i < total_number_of_pdus; ++i) + { + nfapi_preamble_pdu_t* pdu = &(value->preamble_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_PREAMBLE_REL8_TAG, &pdu->preamble_rel8, ppWritePackedMsg, end, pack_preamble_pdu_rel8_value) && + pack_tlv(NFAPI_PREAMBLE_REL9_TAG, &pdu->preamble_rel9, ppWritePackedMsg, end, pack_preamble_pdu_rel9_value) && + pack_tlv(NFAPI_PREAMBLE_REL13_TAG, &pdu->preamble_rel13, ppWritePackedMsg, end, pack_preamble_pdu_rel13_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + + return 1; +} + +static uint8_t pack_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_rach_indication_t *pNfapiMsg = (nfapi_rach_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_RACH_INDICATION_BODY_TAG, &pNfapiMsg->rach_indication_body, ppWritePackedMsg, end, pack_rach_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_srs_indication_fdd_rel8_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel8_t* srs_pdu_rel8 = (nfapi_srs_indication_fdd_rel8_t*)tlv; + + return ( push16(srs_pdu_rel8->doppler_estimation, ppWritePackedMsg, end) && + push16(srs_pdu_rel8->timing_advance, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end) && + push8(srs_pdu_rel8->rb_start, ppWritePackedMsg, end) && + pusharray8(srs_pdu_rel8->snr, NFAPI_NUM_RB_MAX, srs_pdu_rel8->number_of_resource_blocks, ppWritePackedMsg, end)); +} + +static uint8_t pack_srs_indication_fdd_rel9_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel9_t* srs_pdu_rel9 = (nfapi_srs_indication_fdd_rel9_t*)tlv; + + return ( push16(srs_pdu_rel9->timing_advance_r9, ppWritePackedMsg, end) ); +} + +static uint8_t pack_srs_indication_tdd_rel10_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_srs_indication_ttd_rel10_t* srs_pdu_rel10 = (nfapi_srs_indication_ttd_rel10_t*)tlv; + + return ( push8(srs_pdu_rel10->uppts_symbol, ppWritePackedMsg, end) ); + +} + +static uint8_t pack_srs_indication_fdd_rel11_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel11_t* srs_pdu_rel11 = (nfapi_srs_indication_fdd_rel11_t*)tlv; + + return ( push16(srs_pdu_rel11->ul_rtoa, ppWritePackedMsg, end) ) ; +} + +static uint8_t pack_tdd_channel_measurement_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_tdd_channel_measurement_t* value = (nfapi_tdd_channel_measurement_t*)tlv; + + if(!(push8(value->num_prb_per_subband, ppWritePackedMsg, end) && + push8(value->number_of_subbands, ppWritePackedMsg, end) && + push8(value->num_atennas, ppWritePackedMsg, end))) + return 0; + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_subbands; ++idx) + { + if(!(push8(value->subands[idx].subband_index, ppWritePackedMsg, end) && + pusharray16(value->subands[idx].channel, NFAPI_MAX_NUM_PHYSICAL_ANTENNAS, value->num_atennas, ppWritePackedMsg, end))) + return 0; + } + + return 1; +} + +static uint8_t pack_srs_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_srs_indication_body_t *value = (nfapi_srs_indication_body_t*)tlv; + + if( push8(value->number_of_ues, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_ues; + for(; i < total_number_of_pdus; ++i) + { + nfapi_srs_indication_pdu_t* pdu = &(value->srs_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, &pack_rx_ue_information_value) && + pack_tlv(NFAPI_SRS_INDICATION_FDD_REL8_TAG, &pdu->srs_indication_fdd_rel8, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel8_value) && + pack_tlv(NFAPI_SRS_INDICATION_FDD_REL9_TAG, &pdu->srs_indication_fdd_rel9, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel9_value) && + pack_tlv(NFAPI_SRS_INDICATION_TDD_REL10_TAG, &pdu->srs_indication_tdd_rel10, ppWritePackedMsg, end, &pack_srs_indication_tdd_rel10_value) && + pack_tlv(NFAPI_SRS_INDICATION_FDD_REL11_TAG, &pdu->srs_indication_fdd_rel11, ppWritePackedMsg, end, &pack_srs_indication_fdd_rel11_value) && + pack_tlv(NFAPI_TDD_CHANNEL_MEASUREMENT_TAG, &pdu->tdd_channel_measurement, ppWritePackedMsg, end, &pack_tdd_channel_measurement_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + + return 1; +} + +static uint8_t pack_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_srs_indication_t *pNfapiMsg = (nfapi_srs_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_SRS_INDICATION_BODY_TAG, &pNfapiMsg->srs_indication_body, ppWritePackedMsg, end, &pack_srs_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} + +static uint8_t pack_sr_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_sr_indication_body_t* value = (nfapi_sr_indication_body_t*)tlv; + + if(push16(value->number_of_srs, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_srs; + for(; i < total_number_of_pdus; ++i) + { + nfapi_sr_indication_pdu_t* pdu = &(value->sr_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && + pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + return 1; +} + +static uint8_t pack_sr_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_sr_indication_t *pNfapiMsg = (nfapi_sr_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_SR_INDICATION_BODY_TAG, &pNfapiMsg->sr_indication_body, ppWritePackedMsg, end, &pack_sr_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} + +static uint8_t pack_cqi_indication_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_cqi_indication_rel8_t* cqi_pdu_rel8 = (nfapi_cqi_indication_rel8_t*)tlv; + + return ( push16(cqi_pdu_rel8->length, ppWritePackedMsg, end) && + push16(cqi_pdu_rel8->data_offset, ppWritePackedMsg, end) && + push8(cqi_pdu_rel8->ul_cqi, ppWritePackedMsg, end) && + push8(cqi_pdu_rel8->ri, ppWritePackedMsg, end) && + push16(cqi_pdu_rel8->timing_advance, ppWritePackedMsg, end)); +} + +static uint8_t pack_cqi_indication_rel9_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_cqi_indication_rel9_t* cqi_pdu_rel9 = (nfapi_cqi_indication_rel9_t*)tlv; + + return ( push16(cqi_pdu_rel9->length, ppWritePackedMsg, end) && + push16(cqi_pdu_rel9->data_offset, ppWritePackedMsg, end) && + push8(cqi_pdu_rel9->ul_cqi, ppWritePackedMsg, end) && + push8(cqi_pdu_rel9->number_of_cc_reported, ppWritePackedMsg, end) && + pusharray8(cqi_pdu_rel9->ri, NFAPI_CC_MAX, cqi_pdu_rel9->number_of_cc_reported, ppWritePackedMsg, end) && + push16(cqi_pdu_rel9->timing_advance, ppWritePackedMsg, end) && + push16(cqi_pdu_rel9->timing_advance_r9, ppWritePackedMsg, end)); +} + +static uint8_t pack_cqi_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_cqi_indication_body_t* value = (nfapi_cqi_indication_body_t*)tlv; + + if( push16(value->number_of_cqis, ppWritePackedMsg, end) == 0) + return 0; + + // need to calculate the data offset's. This very bittle due the hardcoding + // of the sizes. can not use the sizeof as we have an array for the Rel9 + // info + uint16_t i = 0; + uint16_t offset = 2; // taking into account the number_of_cqis + uint16_t total_number_of_pdus = value->number_of_cqis; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); + + offset += 2; // for the instance length + + if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG) + { + offset += 4 + 6; // sizeof(nfapi_rx_ue_information) - sizeof(nfapi_tl_t) + } + + if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) + { + offset += 4 + 8; + } + + if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) + { + offset += 4 + 10 + pdu->cqi_indication_rel9.number_of_cc_reported; + } + + if(pdu->ul_cqi_information.tl.tag == NFAPI_UL_CQI_INFORMATION_TAG) + { + offset += 4 + 2; + } + } + + // Now update the structure to include the offset + for(i =0; i < total_number_of_pdus; ++i) + { + nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); + + if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) + { + if(pdu->cqi_indication_rel8.data_offset == 1) + { + pdu->cqi_indication_rel8.data_offset = offset; + offset += pdu->cqi_indication_rel8.length; + } + } + + if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) + { + if(pdu->cqi_indication_rel9.data_offset == 1) + { + pdu->cqi_indication_rel9.data_offset = offset; + offset += pdu->cqi_indication_rel9.length; + } + } + + } + + // Write out the cqi information + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end ,pack_rx_ue_information_value) && + pack_tlv(NFAPI_CQI_INDICATION_REL8_TAG, &pdu->cqi_indication_rel8, ppWritePackedMsg, end, pack_cqi_indication_rel8_value) && + pack_tlv(NFAPI_CQI_INDICATION_REL9_TAG, &pdu->cqi_indication_rel9, ppWritePackedMsg, end, pack_cqi_indication_rel9_value) && + pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + + } + + // Write out the cqi raw data + for(i = 0; i < total_number_of_pdus; ++i) + { + uint16_t length = 0; + nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); + + if(pdu->cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) + { + length = pdu->cqi_indication_rel8.length; + } + + if(pdu->cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) + { + length = pdu->cqi_indication_rel9.length; + } + + if( pusharray8(value->cqi_raw_pdu_list[i].pdu, NFAPI_CQI_RAW_MAX_LEN, length, ppWritePackedMsg, end) == 0) + return 0; + } + + return 1; +} + +static uint8_t pack_cqi_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_cqi_indication_t *pNfapiMsg = (nfapi_cqi_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_CQI_INDICATION_BODY_TAG, &pNfapiMsg->cqi_indication_body, ppWritePackedMsg, end, pack_cqi_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +} + +static uint8_t pack_lbt_pdsch_req_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_pdsch_req_pdu_rel13_t* value = (nfapi_lbt_pdsch_req_pdu_rel13_t*)tlv; + + return ( push32(value->handle, ppWritePackedMsg, end) && + push32(value->mp_cca, ppWritePackedMsg, end) && + push32(value->n_cca, ppWritePackedMsg, end) && + push32(value->offset, ppWritePackedMsg, end) && + push32(value->lte_txop_sf, ppWritePackedMsg, end) && + push16(value->txop_sfn_sf_end, ppWritePackedMsg, end) && + push32(value->lbt_mode, ppWritePackedMsg, end)); +} + +static uint8_t pack_lbt_drs_req_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_drs_req_pdu_rel13_t* value = (nfapi_lbt_drs_req_pdu_rel13_t*)tlv; + + return ( push32(value->handle, ppWritePackedMsg, end) && + push32(value->offset, ppWritePackedMsg, end) && + push16(value->sfn_sf_end, ppWritePackedMsg, end) && + push32(value->lbt_mode, ppWritePackedMsg, end)); +} + +static uint8_t pack_lbt_dl_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_dl_config_request_body_t* value = (nfapi_lbt_dl_config_request_body_t*)tlv; + + if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(; i < total_number_of_pdus; ++i) + { + nfapi_lbt_dl_config_request_pdu_t* pdu = &(value->lbt_dl_config_req_pdu_list[i]); + + if( push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) + return 0; + + // Put a 0 size in and then determine the size after the pdu + // has been writen and write the calculated size + uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; + pdu->pdu_size = 0; + if( push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_LBT_DL_CONFIG_REQUEST_PDSCH_PDU_TYPE: + { + if( pack_tlv(NFAPI_LBT_PDSCH_REQ_PDU_REL13_TAG, &pdu->lbt_pdsch_req_pdu.lbt_pdsch_req_pdu_rel13, ppWritePackedMsg, end, pack_lbt_pdsch_req_pdu_rel13_value) == 0) + return 0; + } + break; + case NFAPI_LBT_DL_CONFIG_REQUEST_DRS_PDU_TYPE: + { + if(pack_tlv(NFAPI_LBT_DRS_REQ_PDU_REL13_TAG, &pdu->lbt_drs_req_pdu.lbt_drs_req_pdu_rel13, ppWritePackedMsg, end, pack_lbt_drs_req_pdu_rel13_value) == 0) + return 0; + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL_CONFIG.request invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + + // add 1 for the pdu_type. The delta will include the pdu_size + pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); + push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); + } + + return 1; +} + +static uint8_t pack_lbt_pdsch_rsp_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_pdsch_rsp_pdu_rel13_t* value = (nfapi_lbt_pdsch_rsp_pdu_rel13_t*)tlv; + + return ( push32(value->handle, ppWritePackedMsg, end) && + push32(value->result, ppWritePackedMsg, end) && + push32(value->lte_txop_symbols, ppWritePackedMsg, end) && + push32(value->initial_partial_sf, ppWritePackedMsg, end)); +} + +static uint8_t pack_lbt_drs_rsp_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_drs_rsp_pdu_rel13_t* value = (nfapi_lbt_drs_rsp_pdu_rel13_t*)tlv; + + return ( push32(value->handle, ppWritePackedMsg, end) && + push32(value->result, ppWritePackedMsg, end)); +} + +static uint8_t pack_lbt_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_config_request_t *pNfapiMsg = (nfapi_lbt_dl_config_request_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_LBT_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->lbt_dl_config_request_body, ppWritePackedMsg, end, &pack_lbt_dl_config_request_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_lbt_dl_config_indication_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_lbt_dl_indication_body_t* value = (nfapi_lbt_dl_indication_body_t*)tlv; + + if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(; i < total_number_of_pdus; ++i) + { + nfapi_lbt_dl_indication_pdu_t* pdu = &(value->lbt_indication_pdu_list[i]); + + if( push8(pdu->pdu_type, ppWritePackedMsg, end) == 0) + return 0; + + // Put a 0 size in and then determine the size after the pdu + // has been writen and write the calculated size + uint8_t* pWritePackedMsgPduSize = *ppWritePackedMsg; + pdu->pdu_size = 0; + + if(push8(pdu->pdu_size, ppWritePackedMsg, end) == 0) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_LBT_DL_RSP_PDSCH_PDU_TYPE: + { + if( pack_tlv(NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG, &pdu->lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13, ppWritePackedMsg, end, pack_lbt_pdsch_rsp_pdu_rel13_value) == 0) + return 0; + } + break; + case NFAPI_LBT_DL_RSP_DRS_PDU_TYPE: + { + if( pack_tlv(NFAPI_LBT_DRS_RSP_PDU_REL13_TAG, &pdu->lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13, ppWritePackedMsg, end, pack_lbt_drs_rsp_pdu_rel13_value) == 0) + return 0; + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL.indication body invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + + // add 1 for the pdu_type. The delta will include the pdu_size + pdu->pdu_size = 1 + (*ppWritePackedMsg - pWritePackedMsgPduSize); + push8(pdu->pdu_size, &pWritePackedMsgPduSize, end); + } + + return 1; +} + +static uint8_t pack_lbt_dl_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_indication_t *pNfapiMsg = (nfapi_lbt_dl_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_LBT_DL_INDICATION_BODY_TAG, &pNfapiMsg->lbt_dl_indication_body, ppWritePackedMsg, end, &pack_lbt_dl_config_indication_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_nb_harq_indication_fdd_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_harq_indication_fdd_rel13_t* nb_harq_indication_fdd_rel13 = (nfapi_nb_harq_indication_fdd_rel13_t*)tlv; + + return ( push8(nb_harq_indication_fdd_rel13->harq_tb1, ppWritePackedMsg, end) ); +} + +static uint8_t pack_nb_harq_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nb_harq_indication_body_t* value = (nfapi_nb_harq_indication_body_t*)tlv; + + if( push16(value->number_of_harqs, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_harqs = value->number_of_harqs; + for(; i < total_number_of_harqs; ++i) + { + nfapi_nb_harq_indication_pdu_t* pdu = &(value->nb_harq_pdu_list[i]); + + uint8_t* instance_length_p = *ppWritePackedMsg; + if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + return 0; + + if(!(pack_tlv(NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, ppWritePackedMsg, end, pack_rx_ue_information_value) && + pack_tlv(NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG, &pdu->nb_harq_indication_fdd_rel13, ppWritePackedMsg, end, pack_nb_harq_indication_fdd_rel13_value) && + pack_tlv(NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, ppWritePackedMsg, end, pack_ul_cqi_information_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + push16(instance_length, &instance_length_p, end); + } + + return 1; +} + + +static uint8_t pack_nb_harq_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nb_harq_indication_t *pNfapiMsg = (nfapi_nb_harq_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_NB_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->nb_harq_indication_body, ppWritePackedMsg, end, &pack_nb_harq_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_nrach_indication_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nrach_indication_pdu_rel13_t* nrach_indication_fdd_rel13 = (nfapi_nrach_indication_pdu_rel13_t*)tlv; + + return ( push16(nrach_indication_fdd_rel13->rnti, ppWritePackedMsg, end) && + push8(nrach_indication_fdd_rel13->initial_sc, ppWritePackedMsg, end) && + push16(nrach_indication_fdd_rel13->timing_advance, ppWritePackedMsg, end) && + push8(nrach_indication_fdd_rel13->nrach_ce_level, ppWritePackedMsg, end)); +} + + +static uint8_t pack_nrach_indication_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv; + + if( push8(value->number_of_initial_scs_detected, ppWritePackedMsg, end) == 0) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_initial_scs_detected = value->number_of_initial_scs_detected; + for(; i < total_number_of_initial_scs_detected; ++i) + { + nfapi_nrach_indication_pdu_t* pdu = &(value->nrach_pdu_list[i]); + + //uint8_t* instance_length_p = *ppWritePackedMsg; + //if(!push16(pdu->instance_length, ppWritePackedMsg, end)) + // return 0; + + if(!(pack_tlv(NFAPI_NRACH_INDICATION_REL13_TAG, &pdu->nrach_indication_rel13, ppWritePackedMsg, end, pack_nrach_indication_rel13_value))) + return 0; + + // calculate the instance length subtracting the size of the instance + // length feild + //uint16_t instance_length = *ppWritePackedMsg - instance_length_p - 2; + //push16(instance_length, &instance_length_p, end); + } + + return 1; +} + +static uint8_t pack_nrach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nrach_indication_t *pNfapiMsg = (nfapi_nrach_indication_t*)msg; + + return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && + pack_tlv(NFAPI_NRACH_INDICATION_BODY_TAG, &pNfapiMsg->nrach_indication_body, ppWritePackedMsg, end, &pack_nrach_indication_body_value) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_nr_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_dl_node_sync_t *pNfapiMsg = (nfapi_nr_dl_node_sync_t*)msg; + + return ( push32(pNfapiMsg->t1, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->delta_sfn_slot, ppWritePackedMsg, end) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t*)msg; + + return ( push32(pNfapiMsg->t1, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->delta_sfn_sf, ppWritePackedMsg, end) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_nr_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_ul_node_sync_t *pNfapiMsg = (nfapi_nr_ul_node_sync_t*)msg; + + return (push32(pNfapiMsg->t1, ppWritePackedMsg, end) && + push32(pNfapiMsg->t2, ppWritePackedMsg, end) && + push32(pNfapiMsg->t3, ppWritePackedMsg, end) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t*)msg; + + return (push32(pNfapiMsg->t1, ppWritePackedMsg, end) && + push32(pNfapiMsg->t2, ppWritePackedMsg, end) && + push32(pNfapiMsg->t3, ppWritePackedMsg, end) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t*)msg; + + return (push32(pNfapiMsg->last_sfn_sf, ppWritePackedMsg, end) && + push32(pNfapiMsg->time_since_last_timing_info, ppWritePackedMsg, end) && + push32(pNfapiMsg->dl_config_jitter, ppWritePackedMsg, end) && + push32(pNfapiMsg->tx_request_jitter, ppWritePackedMsg, end) && + push32(pNfapiMsg->ul_config_jitter, ppWritePackedMsg, end) && + push32(pNfapiMsg->hi_dci0_jitter, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->dl_config_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->tx_request_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->ul_config_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->hi_dci0_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->dl_config_earliest_arrival, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->tx_request_earliest_arrival, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->ul_config_earliest_arrival, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->hi_dci0_earliest_arrival, ppWritePackedMsg, end) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + +static uint8_t pack_nr_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_timing_info_t *pNfapiMsg = (nfapi_nr_timing_info_t*)msg; + + return (push32(pNfapiMsg->last_sfn, ppWritePackedMsg, end) && + push32(pNfapiMsg->last_slot, ppWritePackedMsg, end) && + push32(pNfapiMsg->time_since_last_timing_info, ppWritePackedMsg, end) && + push32(pNfapiMsg->dl_tti_jitter, ppWritePackedMsg, end) && + push32(pNfapiMsg->tx_data_request_jitter, ppWritePackedMsg, end) && + push32(pNfapiMsg->ul_tti_jitter, ppWritePackedMsg, end) && + push32(pNfapiMsg->ul_dci_jitter, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->dl_tti_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->tx_data_request_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->ul_tti_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->ul_dci_latest_delay, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->dl_tti_earliest_arrival, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->tx_data_request_earliest_arrival, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->ul_tti_earliest_arrival, ppWritePackedMsg, end) && + pushs32(pNfapiMsg->ul_dci_earliest_arrival, ppWritePackedMsg, end) && + pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); +} + + + +// Main pack function - public + +int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config) +{ + nfapi_p7_message_header_t *pMessageHeader = pMessageBuf; + uint8_t *pWritePackedMessage = pPackedBuf; + uint8_t *pPackedLengthField = &pWritePackedMessage[4]; + uint8_t *end = pPackedBuf + packedBufLen; + + if (pMessageBuf == NULL || pPackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n"); + return -1; + } + /* + printf("\n P7 MESSAGE SENT: \n"); + for(int i=0; i< packedBufLen; i++){ + printf("%d", *(uint8_t *)(pMessageBuf + i)); + } + printf("\n"); + */ + // process the header + if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && + push16(pMessageHeader->message_id, &pWritePackedMessage, end) && + push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) && + push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end) && + push32(0/*pMessageHeader->checksum*/, &pWritePackedMessage, end) && + push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end))) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n"); + return -1; + } + + if (pMessageHeader->message_id != NFAPI_TIMING_INFO) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__, pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp); + } + // look for the specific message + uint8_t result = 0; + switch (pMessageHeader->message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + result = pack_dl_tti_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + result = pack_ul_tti_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + result = pack_tx_data_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + result = pack_ul_dci_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + case NFAPI_UE_RELEASE_REQUEST: result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config); break; @@ -2716,1819 +3414,2661 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config); break; - case NFAPI_HARQ_INDICATION: - result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_CRC_INDICATION: - result = pack_crc_indication(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_RX_ULSCH_INDICATION: - //printf("RX ULSCH\n"); - result = pack_rx_ulsch_indication(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_RACH_INDICATION: - result = pack_rach_indication(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_SRS_INDICATION: - result = pack_srs_indication(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_RX_SR_INDICATION: - result = pack_sr_indication(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_RX_CQI_INDICATION: - result = pack_cqi_indication(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_LBT_DL_CONFIG_REQUEST: - result = pack_lbt_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_LBT_DL_INDICATION: - result = pack_lbt_dl_indication(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_NB_HARQ_INDICATION: - result = pack_nb_harq_indication(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_NRACH_INDICATION: - result = pack_nrach_indication(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_DL_NODE_SYNC: - result = pack_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_UL_NODE_SYNC: - result = pack_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config); - break; - - case NFAPI_TIMING_INFO: - result = pack_timing_info(pMessageHeader, &pWritePackedMessage, end, config); - break; - - default: - { - if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && - pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) - { - if(config && config->pack_p7_vendor_extension) - { - result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config); - } - else - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, pMessageHeader->message_id); - } - } - else - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id); - } - } - break; - } - - if(result == 0) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n"); - return -1; - } - - // check for a valid message length - uintptr_t msgHead = (uintptr_t)pPackedBuf; - uintptr_t msgEnd = (uintptr_t)pWritePackedMessage; - uint32_t packedMsgLen = msgEnd - msgHead; - uint16_t packedMsgLen16; - if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen); - return -1; - } - else - { - packedMsgLen16 = (uint16_t)packedMsgLen; - } - - // Update the message length in the header - pMessageHeader->message_length = packedMsgLen16; - - if(!push16(packedMsgLen16, &pPackedLengthField, end)) - return -1; - - if(1) - { - //quick test - if(pMessageHeader->message_length != packedMsgLen) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", packedMsgLen, pMessageHeader->message_length, pMessageHeader->message_id); - } - } - - return (packedMsgLen); -} - - - -// Unpack routines - -static uint8_t unpack_dl_config_dci_dl_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel8_t* dci_dl_pdu_rel8 = (nfapi_dl_config_dci_dl_pdu_rel8_t*)tlv; - - return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->dci_format, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->cce_idx, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->aggregation_level, end) && - pull16(ppReadPackedMsg, &dci_dl_pdu_rel8->rnti, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->resource_allocation_type, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->virtual_resource_block_assignment_flag, end) && - pull32(ppReadPackedMsg, &dci_dl_pdu_rel8->resource_block_coding, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->mcs_1, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->redundancy_version_1, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->new_data_indicator_1, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->transport_block_to_codeword_swap_flag, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->mcs_2, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->redundancy_version_2, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->new_data_indicator_2, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->harq_process, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->tpmi, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->pmi, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->precoding_information, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->tpc, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->downlink_assignment_index, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->ngap, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->transport_block_size_index, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->downlink_power_offset, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->allocate_prach_flag, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->preamble_index, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->prach_mask_index, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->rnti_type, end) && - pull16(ppReadPackedMsg, &dci_dl_pdu_rel8->transmission_power, end)); - -} - -static uint8_t unpack_dl_config_dci_dl_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel9_t* dci_dl_pdu_rel9 = (nfapi_dl_config_dci_dl_pdu_rel9_t*)tlv; - - return ( pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->mcch_flag, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->mcch_change_notification, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->scrambling_identity, end)); -} - -static uint8_t unpack_dl_config_dci_dl_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel10_t* dci_dl_pdu_rel10 = (nfapi_dl_config_dci_dl_pdu_rel10_t*)tlv; - - return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->cross_carrier_scheduling_flag, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->carrier_indicator, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->srs_flag, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->srs_request, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->antenna_ports_scrambling_and_layers, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->total_dci_length_including_padding, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->n_dl_rb, end)); -} - -static uint8_t unpack_dl_config_dci_dl_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel11_t* dci_dl_pdu_rel11 = (nfapi_dl_config_dci_dl_pdu_rel11_t*)tlv; - - return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel11->harq_ack_resource_offset, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel11->pdsch_re_mapping_quasi_co_location_indicator, end)); -} - -static uint8_t unpack_dl_config_dci_dl_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel12_t* dci_dl_pdu_rel12 = (nfapi_dl_config_dci_dl_pdu_rel12_t*)tlv; - - return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->primary_cell_type, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->ul_dl_configuration_flag, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->number_ul_dl_configurations, end) && - pullarray8(ppReadPackedMsg, dci_dl_pdu_rel12->ul_dl_configuration_indication, NFAPI_MAX_UL_DL_CONFIGURATIONS, dci_dl_pdu_rel12->number_ul_dl_configurations, end)); -} - -static uint8_t unpack_tpm_value(uint8_t **ppReadPackedMsg, nfapi_dl_config_dci_dl_tpm_t *value, uint8_t *end) -{ - if(!(pull8(ppReadPackedMsg, &value->num_prb_per_subband, end) && - pull8(ppReadPackedMsg, &value->number_of_subbands, end) && - pull8(ppReadPackedMsg, &value->num_antennas, end))) - return 0; - - - uint8_t idx = 0; - for(idx = 0; idx < value->number_of_subbands; ++idx) - { - nfapi_dl_config_dci_dl_tpm_subband_info_t* subband_info = &(value->subband_info[idx]); - - if(!(pull8(ppReadPackedMsg, &subband_info->subband_index, end) && - pull8(ppReadPackedMsg, &subband_info->scheduled_ues, end))) - return 0; - - uint8_t antenna_idx = 0; - uint8_t scheduled_ue_idx = 0; - - for(antenna_idx = 0; antenna_idx < value->num_antennas; ++antenna_idx) - { - for(scheduled_ue_idx = 0; scheduled_ue_idx < subband_info->scheduled_ues; ++scheduled_ue_idx) - { - if(!pull16(ppReadPackedMsg, &(subband_info->precoding_value[antenna_idx][scheduled_ue_idx]), end)) - return 0; - } - } - - } - - - return 1; - -} - - -static uint8_t unpack_dl_config_dci_dl_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dci_dl_pdu_rel13_t* dci_dl_pdu_rel13 = (nfapi_dl_config_dci_dl_pdu_rel13_t*)tlv; - - // If the length is greater than 5 then the TPM struct flag and possiably the TPM structure have been - // added - uint8_t tpm_struct_flag_present = dci_dl_pdu_rel13->tl.length > 5; - dci_dl_pdu_rel13->tpm_struct_flag = 0; - - return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->laa_end_partial_sf_flag, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->laa_end_partial_sf_configuration, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->initial_lbt_sf, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->codebook_size_determination, end) && - pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->drms_table_flag, end) && - ( (tpm_struct_flag_present == 1) ? pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->tpm_struct_flag, end) : 1) && - ( (tpm_struct_flag_present == 1 && dci_dl_pdu_rel13->tpm_struct_flag == 1) ? unpack_tpm_value(ppReadPackedMsg, &dci_dl_pdu_rel13->tpm, end) : 1)); - -} - -static uint8_t unpack_dl_config_bch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_bch_pdu_rel8_t* bch_pdu_rel8 = (nfapi_dl_config_bch_pdu_rel8_t*)tlv; - - return ( pull16(ppReadPackedMsg, &bch_pdu_rel8->length, end) && - pull16(ppReadPackedMsg, (uint16_t *)&bch_pdu_rel8->pdu_index, end) && - pull16(ppReadPackedMsg, &bch_pdu_rel8->transmission_power, end)); -} - -static uint8_t unpack_dl_config_mch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_mch_pdu_rel8_t* mch_pdu_rel8 = (nfapi_dl_config_mch_pdu_rel8_t*)tlv; - - return (pull16(ppReadPackedMsg, &mch_pdu_rel8->length, end) && - pull16(ppReadPackedMsg, (uint16_t *)&mch_pdu_rel8->pdu_index, end) && - pull16(ppReadPackedMsg, &mch_pdu_rel8->rnti, end) && - pull8(ppReadPackedMsg, &mch_pdu_rel8->resource_allocation_type, end) && - pull32(ppReadPackedMsg, &mch_pdu_rel8->resource_block_coding, end) && - pull8(ppReadPackedMsg, &mch_pdu_rel8->modulation, end) && - pull16(ppReadPackedMsg, &mch_pdu_rel8->transmission_power, end) && - pull16(ppReadPackedMsg, &mch_pdu_rel8->mbsfn_area_id, end)); -} - -static uint8_t unpack_dl_config_dlsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel8_t* dlsch_pdu_rel8 = (nfapi_dl_config_dlsch_pdu_rel8_t*)tlv; - - if (!(pull16(ppReadPackedMsg, &dlsch_pdu_rel8->length, end) && - pull16(ppReadPackedMsg, (uint16_t *)&dlsch_pdu_rel8->pdu_index, end) && - pull16(ppReadPackedMsg, &dlsch_pdu_rel8->rnti, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->resource_allocation_type, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->virtual_resource_block_assignment_flag, end) && - pull32(ppReadPackedMsg, &dlsch_pdu_rel8->resource_block_coding, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->modulation, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->redundancy_version, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transport_blocks, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transport_block_to_codeword_swap_flag, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transmission_scheme, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->number_of_layers, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->number_of_subbands, end) && - pullarray8(ppReadPackedMsg, dlsch_pdu_rel8->codebook_index, NFAPI_MAX_NUM_SUBBANDS, dlsch_pdu_rel8->number_of_subbands, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->ue_category_capacity, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->pa, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->delta_power_offset_index, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->ngap, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->nprb, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transmission_mode, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->num_bf_prb_per_subband, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->num_bf_vector, end))) - return 0; - - uint16_t j = 0; - for(j = 0; j < dlsch_pdu_rel8->num_bf_vector; ++j) - { - if(!(pull8(ppReadPackedMsg, &dlsch_pdu_rel8->bf_vector[j].subband_index, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel8->bf_vector[j].num_antennas, end) && - pullarray16(ppReadPackedMsg, dlsch_pdu_rel8->bf_vector[j].bf_value, NFAPI_MAX_NUM_ANTENNAS, dlsch_pdu_rel8->bf_vector[j].num_antennas, end))) - return 0; - } - return 1; -} -static uint8_t unpack_dl_config_dlsch_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel9_t* dlsch_pdu_rel9 = (nfapi_dl_config_dlsch_pdu_rel9_t*)tlv; - return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel9->nscid, end) ); -} -static uint8_t unpack_dl_config_dlsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel10_t* dlsch_pdu_rel10 = (nfapi_dl_config_dlsch_pdu_rel10_t*)tlv; - - return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_flag, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_resource_config_r10, end) && - pull16(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_zero_tx_power_resource_config_bitmap_r10, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_number_nzp_configuration, end) && - pullarray8(ppReadPackedMsg, dlsch_pdu_rel10->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, dlsch_pdu_rel10->csi_rs_number_nzp_configuration, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel10->pdsch_start, end)) ; -} -static uint8_t unpack_dl_config_dlsch_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel11_t* dlsch_pdu_rel11 = (nfapi_dl_config_dlsch_pdu_rel11_t*)tlv; - - return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel11->drms_config_flag, end) && - pull16(ppReadPackedMsg, &dlsch_pdu_rel11->drms_scrambling, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel11->csi_config_flag, end) && - pull16(ppReadPackedMsg, &dlsch_pdu_rel11->csi_scrambling, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_flag, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_atenna_ports, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_freq_shift, end)); -} -static uint8_t unpack_dl_config_dlsch_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel12_t* dlsch_pdu_rel12 = (nfapi_dl_config_dlsch_pdu_rel12_t*)tlv; - - return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel12->altcqi_table_r12, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel12->maxlayers, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel12->n_dl_harq, end)); -} -static uint8_t unpack_dl_config_dlsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_dlsch_pdu_rel13_t* dlsch_pdu_rel13 = (nfapi_dl_config_dlsch_pdu_rel13_t*)tlv; - - return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel13->dwpts_symbols, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel13->initial_lbt_sf, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel13->ue_type, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel13->pdsch_payload_type, end) && - pull16(ppReadPackedMsg, &dlsch_pdu_rel13->initial_transmission_sf_io, end) && - pull8(ppReadPackedMsg, &dlsch_pdu_rel13->drms_table_flag, end)); -} - -static uint8_t unpack_dl_config_pch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_pch_pdu_rel8_t* pch_pdu_rel8 = (nfapi_dl_config_pch_pdu_rel8_t*)tlv; - - return ( pull16(ppReadPackedMsg, &pch_pdu_rel8->length, end) && - pull16(ppReadPackedMsg, (uint16_t *)&pch_pdu_rel8->pdu_index, end) && - pull16(ppReadPackedMsg, &pch_pdu_rel8->p_rnti, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->resource_allocation_type, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->virtual_resource_block_assignment_flag, end) && - pull32(ppReadPackedMsg, &pch_pdu_rel8->resource_block_coding, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->mcs, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->redundancy_version, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->number_of_transport_blocks, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->transport_block_to_codeword_swap_flag, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->transmission_scheme, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->number_of_layers, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->codebook_index, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->ue_category_capacity, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->pa, end) && - pull16(ppReadPackedMsg, &pch_pdu_rel8->transmission_power, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->nprb, end) && - pull8(ppReadPackedMsg, &pch_pdu_rel8->ngap, end)); -} -static uint8_t unpack_dl_config_pch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_pch_pdu_rel13_t* pch_pdu_rel13 = (nfapi_dl_config_pch_pdu_rel13_t*)tlv; - - return ( pull8(ppReadPackedMsg, &pch_pdu_rel13->ue_mode, end) && - pull16(ppReadPackedMsg, &pch_pdu_rel13->initial_transmission_sf_io, end)); -} - -static uint8_t unpack_dl_config_prs_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_prs_pdu_rel9_t* prs_pdu_rel9 = (nfapi_dl_config_prs_pdu_rel9_t*)tlv; - - return ( pull16(ppReadPackedMsg, &prs_pdu_rel9->transmission_power, end) && - pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_bandwidth, end) && - pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_cyclic_prefix_type, end) && - pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_muting, end)); -} - -static uint8_t unpack_dl_config_csi_rs_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_csi_rs_pdu_rel10_t* csi_rs_pdu_rel10 = (nfapi_dl_config_csi_rs_pdu_rel10_t*)tlv; - - return ( pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_antenna_port_count_r10, end) && - pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_resource_config_r10, end) && - pull16(ppReadPackedMsg, &csi_rs_pdu_rel10->transmission_power, end) && - pull16(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_zero_tx_power_resource_config_bitmap_r10, end) && - pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_number_of_nzp_configuration, end) && - pullarray8(ppReadPackedMsg, csi_rs_pdu_rel10->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, csi_rs_pdu_rel10->csi_rs_number_of_nzp_configuration, end)); -} - -static uint8_t unpack_dl_config_csi_rs_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_csi_rs_pdu_rel13_t* csi_rs_pdu_rel13 = (nfapi_dl_config_csi_rs_pdu_rel13_t*)tlv; - - if (!(pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->csi_rs_class, end) && - pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->cdm_type, end) && - pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->num_bf_vector, end))) - return 0; - - - uint16_t idx =0; - for(idx = 0; idx < csi_rs_pdu_rel13->num_bf_vector; ++idx) - { - if(!(pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->bf_vector[idx].csi_rs_resource_index, end))) - return 0; - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : HOW TO DECODE BF VALUE \n"); - //pullarray16(ppReadPackedMsg, &csi_rs_pdu_rel13->bf_vector[idx].bf_vector, ??); - } - return 1; -} - -static uint8_t unpack_dl_config_epdcch_params_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_epdcch_parameters_rel11_t* epdcch_params_rel11 = (nfapi_dl_config_epdcch_parameters_rel11_t*)tlv; - - return (pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_resource_assignment_flag, end) && - pull16(ppReadPackedMsg, &epdcch_params_rel11->epdcch_id, end) && - pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_start_symbol, end) && - pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_num_prb, end) && - pullarray8(ppReadPackedMsg, epdcch_params_rel11->epdcch_prb_index, NFAPI_MAX_EPDCCH_PRB, epdcch_params_rel11->epdcch_num_prb, end) && - pull8(ppReadPackedMsg, &epdcch_params_rel11->bf_vector.subband_index, end) && - pull8(ppReadPackedMsg, &epdcch_params_rel11->bf_vector.num_antennas, end) && - pullarray16(ppReadPackedMsg, epdcch_params_rel11->bf_vector.bf_value, NFAPI_MAX_NUM_ANTENNAS, epdcch_params_rel11->bf_vector.num_antennas, end)); -} - -static uint8_t unpack_dl_config_epdcch_params_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_epdcch_parameters_rel13_t* epdcch_params_rel13 = (nfapi_dl_config_epdcch_parameters_rel13_t*)tlv; - - return ( pull8(ppReadPackedMsg, &epdcch_params_rel13->dwpts_symbols, end) && - pull8(ppReadPackedMsg, &epdcch_params_rel13->initial_lbt_sf, end)); -} - -static uint8_t unpack_dl_config_mpdcch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_mpdcch_pdu_rel13_t* mpdcch_params_rel13 = (nfapi_dl_config_mpdcch_pdu_rel13_t*)tlv; - - - return ( pull8(ppReadPackedMsg, &mpdcch_params_rel13->mpdcch_narrow_band, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->number_of_prb_pairs, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->resource_block_assignment, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->mpdcch_tansmission_type, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->start_symbol, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->ecce_index, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->aggregation_level, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->rnti_type, end) && - pull16(ppReadPackedMsg, &mpdcch_params_rel13->rnti, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->ce_mode, end) && - pull16(ppReadPackedMsg, &mpdcch_params_rel13->drms_scrambling_init, end) && - pull16(ppReadPackedMsg, &mpdcch_params_rel13->initial_transmission_sf_io, end) && - pull16(ppReadPackedMsg, &mpdcch_params_rel13->transmission_power, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->dci_format, end) && - pull16(ppReadPackedMsg, &mpdcch_params_rel13->resource_block_coding, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->mcs, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->pdsch_reptition_levels, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->redundancy_version, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->new_data_indicator, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->harq_process, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpmi_length, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpmi, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->pmi_flag, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->pmi, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->harq_resource_offset, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->dci_subframe_repetition_number, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpc, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->downlink_assignment_index_length, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->downlink_assignment_index, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->allocate_prach_flag, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->preamble_index, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->prach_mask_index, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->starting_ce_level, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->srs_request, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->antenna_ports_and_scrambling_identity_flag, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->antenna_ports_and_scrambling_identity, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->frequency_hopping_enabled_flag, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->paging_direct_indication_differentiation_flag, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->direct_indication, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->total_dci_length_including_padding, end) && - pull8(ppReadPackedMsg, &mpdcch_params_rel13->number_of_tx_antenna_ports, end) && - pullarray16(ppReadPackedMsg, mpdcch_params_rel13->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, mpdcch_params_rel13->number_of_tx_antenna_ports, end)); -} - - -static uint8_t unpack_dl_config_nbch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_nbch_pdu_rel13_t* nbch_params_rel13 = (nfapi_dl_config_nbch_pdu_rel13_t*)tlv; - - return ( pull16(ppReadPackedMsg, &nbch_params_rel13->length, end) && - pull16(ppReadPackedMsg, (uint16_t *)&nbch_params_rel13->pdu_index, end) && - pull16(ppReadPackedMsg, &nbch_params_rel13->transmission_power, end) && - pull16(ppReadPackedMsg, &nbch_params_rel13->hyper_sfn_2_lsbs, end)); -} - -static uint8_t unpack_dl_config_npdcch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_npdcch_pdu_rel13_t* npdcch_params_rel13 = (nfapi_dl_config_npdcch_pdu_rel13_t*)tlv; - - return ( pull16(ppReadPackedMsg, &npdcch_params_rel13->length, end) && - pull16(ppReadPackedMsg, (uint16_t *)&npdcch_params_rel13->pdu_index, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->ncce_index, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->aggregation_level, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->start_symbol, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->rnti_type, end) && - pull16(ppReadPackedMsg, &npdcch_params_rel13->rnti, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->scrambling_reinitialization_batch_index, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->dci_format, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->scheduling_delay, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->resource_assignment, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->repetition_number, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->mcs, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->new_data_indicator, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->harq_ack_resource, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->npdcch_order_indication, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->starting_number_of_nprach_repetitions, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->subcarrier_indication_of_nprach, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->paging_direct_indication_differentation_flag, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->direct_indication, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->dci_subframe_repetition_number, end) && - pull8(ppReadPackedMsg, &npdcch_params_rel13->total_dci_length_including_padding, end)); -} - -static uint8_t unpack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_dl_config_ndlsch_pdu_rel13_t* ndlsch_params_rel13 = (nfapi_dl_config_ndlsch_pdu_rel13_t*)tlv; - - return ( pull16(ppReadPackedMsg, &ndlsch_params_rel13->length, end) && - pull16(ppReadPackedMsg, (uint16_t *)&ndlsch_params_rel13->pdu_index, end) && - pull8(ppReadPackedMsg, &ndlsch_params_rel13->start_symbol, end) && - pull8(ppReadPackedMsg, &ndlsch_params_rel13->rnti_type, end) && - pull16(ppReadPackedMsg, &ndlsch_params_rel13->rnti, end) && - pull16(ppReadPackedMsg, &ndlsch_params_rel13->resource_assignment, end) && - pull16(ppReadPackedMsg, &ndlsch_params_rel13->repetition_number, end) && - pull8(ppReadPackedMsg, &ndlsch_params_rel13->modulation, end) && - pull8(ppReadPackedMsg, &ndlsch_params_rel13->number_of_subframes_for_resource_assignment, end) && - pull8(ppReadPackedMsg, &ndlsch_params_rel13->scrambling_sequence_initialization_cinit, end) && - pull16(ppReadPackedMsg, &ndlsch_params_rel13->sf_idx, end) && - pull8(ppReadPackedMsg, &ndlsch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end)); -} - - -static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv; - - if(!(pull8(ppReadPackedMsg, &value->number_pdcch_ofdm_symbols, end) && - pull8(ppReadPackedMsg, &value->number_dci, end) && - pull16(ppReadPackedMsg, &value->number_pdu, end) && - pull8(ppReadPackedMsg, &value->number_pdsch_rnti, end) && - pull16(ppReadPackedMsg, &value->transmission_power_pcfich, end))) - return 0; - - if(value->number_pdu > NFAPI_DL_CONFIG_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of dl config pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_pdu, NFAPI_DL_CONFIG_MAX_PDU); - return 0; - } - - if(value->number_pdu) - { - value->dl_config_pdu_list = (nfapi_dl_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_dl_config_request_pdu_t) * value->number_pdu, config); - if(value->dl_config_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate dl config pdu list (count:%d)\n", __FUNCTION__, value->number_pdu); - return 0; - } - } - else - { - value->dl_config_pdu_list = 0; - } - - uint16_t i; - uint16_t total_number_of_pdus = value->number_pdu; - for(i = 0; i < total_number_of_pdus; ++i) - { - nfapi_dl_config_request_pdu_t* pdu = &(value->dl_config_pdu_list[i]); - - if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && - pull8(ppReadPackedMsg, &pdu->pdu_size, end))) - return 0; - - uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; - - if(packedPduEnd > end) - { - // pdu end of beyond buffer end - return 0; - } - - switch(pdu->pdu_type) - { - case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, &unpack_dl_config_dci_dl_pdu_rel8_value}, - { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, &unpack_dl_config_dci_dl_pdu_rel9_value}, - { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, &unpack_dl_config_dci_dl_pdu_rel10_value}, - { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel11, &unpack_dl_config_dci_dl_pdu_rel11_value}, - { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel12, &unpack_dl_config_dci_dl_pdu_rel12_value}, - { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel13, &unpack_dl_config_dci_dl_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_DL_CONFIG_BCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, &unpack_dl_config_bch_pdu_rel8_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_DL_CONFIG_MCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG, &pdu->mch_pdu.mch_pdu_rel8, &unpack_dl_config_mch_pdu_rel8_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel8, &unpack_dl_config_dlsch_pdu_rel8_value}, - { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel9, &unpack_dl_config_dlsch_pdu_rel9_value}, - { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel10, &unpack_dl_config_dlsch_pdu_rel10_value}, - { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel11, &unpack_dl_config_dlsch_pdu_rel11_value}, - { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel12, &unpack_dl_config_dlsch_pdu_rel12_value}, - { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel13, &unpack_dl_config_dlsch_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_DL_CONFIG_PCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG, &pdu->pch_pdu.pch_pdu_rel8, &unpack_dl_config_pch_pdu_rel8_value}, - { NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG, &pdu->pch_pdu.pch_pdu_rel13, &unpack_dl_config_pch_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_DL_CONFIG_PRS_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG, &pdu->prs_pdu.prs_pdu_rel9, &unpack_dl_config_prs_pdu_rel9_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel10, &unpack_dl_config_csi_rs_pdu_rel10_value}, - { NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel13, &unpack_dl_config_csi_rs_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel8, &unpack_dl_config_dci_dl_pdu_rel8_value}, - { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel9, &unpack_dl_config_dci_dl_pdu_rel9_value}, - { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel10, &unpack_dl_config_dci_dl_pdu_rel10_value}, - { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel11, &unpack_dl_config_dci_dl_pdu_rel11_value}, - { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel12, &unpack_dl_config_dci_dl_pdu_rel12_value}, - { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel13, &unpack_dl_config_dci_dl_pdu_rel13_value}, - { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG, &pdu->epdcch_pdu.epdcch_params_rel11, &unpack_dl_config_epdcch_params_rel11_value}, - { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG, &pdu->epdcch_pdu.epdcch_params_rel13, &unpack_dl_config_epdcch_params_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG, &pdu->mpdcch_pdu.mpdcch_pdu_rel13, &unpack_dl_config_mpdcch_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG, &pdu->nbch_pdu.nbch_pdu_rel13, &unpack_dl_config_nbch_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG, &pdu->npdcch_pdu.npdcch_pdu_rel13, &unpack_dl_config_npdcch_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - - } - break; - case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG, &pdu->ndlsch_pdu.ndlsch_pdu_rel13, &unpack_dl_config_ndlsch_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - - } - break; - default: - // Need to log an error - break; - } - } - - return 1; -} - -static uint8_t unpack_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, &unpack_dl_config_request_body_value}, - }; - - return ( pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_ul_config_ulsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_pdu_rel8_t* ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t*)tlv; - - return (pull32(ppReadPackedMsg, &ulsch_pdu_rel8->handle, end) && - pull16(ppReadPackedMsg, &ulsch_pdu_rel8->size, end) && - pull16(ppReadPackedMsg, &ulsch_pdu_rel8->rnti, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->resource_block_start, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->number_of_resource_blocks, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->modulation_type, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->cyclic_shift_2_for_drms, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->frequency_hopping_enabled_flag, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->frequency_hopping_bits, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->new_data_indication, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->redundancy_version, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->harq_process_number, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->ul_tx_mode, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->current_tx_nb, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel8->n_srs, end )); -} -static uint8_t unpack_ul_config_ulsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_pdu_rel10_t* ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t*)tlv; - - return (pull8(ppReadPackedMsg, &ulsch_pdu_rel10->resource_allocation_type, end) && - pull32(ppReadPackedMsg, &ulsch_pdu_rel10->resource_block_coding, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel10->transport_blocks, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel10->transmission_scheme, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel10->number_of_layers, end) & - pull8(ppReadPackedMsg, &ulsch_pdu_rel10->codebook_index, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel10->disable_sequence_hopping_flag, end)); -} -static uint8_t unpack_ul_config_ulsch_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_pdu_rel11_t* ulsch_pdu_rel11 = (nfapi_ul_config_ulsch_pdu_rel11_t*)tlv; - - return ( pull8(ppReadPackedMsg, &ulsch_pdu_rel11->virtual_cell_id_enabled_flag, end) && - pull16(ppReadPackedMsg, &ulsch_pdu_rel11->npusch_identity, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel11->dmrs_config_flag, end) && - pull16(ppReadPackedMsg, &ulsch_pdu_rel11->ndmrs_csh_identity, end)); -} -static uint8_t unpack_ul_config_ulsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_pdu_rel13_t* ulsch_pdu_rel13 = (nfapi_ul_config_ulsch_pdu_rel13_t*)tlv; - - return (pull8(ppReadPackedMsg, &ulsch_pdu_rel13->ue_type, end) && - pull16(ppReadPackedMsg, &ulsch_pdu_rel13->total_number_of_repetitions, end) && - pull16(ppReadPackedMsg, &ulsch_pdu_rel13->repetition_number, end) && - pull16(ppReadPackedMsg, &ulsch_pdu_rel13->initial_transmission_sf_io, end) && - pull8(ppReadPackedMsg, &ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, end)); -} -static uint8_t unpack_ul_config_cqi_ri_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_ri_information_rel8_t* cqi_ri_info_rel8 = (nfapi_ul_config_cqi_ri_information_rel8_t*)tlv; - - return (pull8(ppReadPackedMsg, &cqi_ri_info_rel8->dl_cqi_pmi_size_rank_1, end) && - pull8(ppReadPackedMsg, &cqi_ri_info_rel8->dl_cqi_pmi_size_rank_greater_1, end) && - pull8(ppReadPackedMsg, &cqi_ri_info_rel8->ri_size, end) && - pull8(ppReadPackedMsg, &cqi_ri_info_rel8->delta_offset_cqi, end) && - pull8(ppReadPackedMsg, &cqi_ri_info_rel8->delta_offset_ri, end)); -} - -static uint8_t unpack_ul_config_cqi_ri_info_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_ri_information_rel9_t* cqi_ri_info_rel9 = (nfapi_ul_config_cqi_ri_information_rel9_t*)tlv; - - if(!(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->report_type, end) && - pull8(ppReadPackedMsg, &cqi_ri_info_rel9->delta_offset_cqi, end) && - pull8(ppReadPackedMsg, &cqi_ri_info_rel9->delta_offset_ri, end))) - return 0; - - switch(cqi_ri_info_rel9->report_type) - { - case NFAPI_CSI_REPORT_TYPE_PERIODIC: - { - if(!(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size, end) && - pull8(ppReadPackedMsg, &cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.control_type, end))) - return 0; - } - break; - case NFAPI_CSI_REPORT_TYPE_APERIODIC: - { - if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc, end) ==0) - return 0; - - uint8_t i; - for(i = 0; i < cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc; ++i) - { - if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, end) == 0) - return 0; - - uint8_t j; - for(j = 0; j < 8; ++j) - { - if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], end) == 0) - return 0; - } - } - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel9->report_type ); - return 0; - } - break; - }; - return 1; -} - -// NOTE : This function is a little unconventional as we uese the side to -// determine the report type -static uint8_t unpack_ul_config_cqi_ri_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_ri_information_rel13_t* cqi_ri_info_rel13 = (nfapi_ul_config_cqi_ri_information_rel13_t*)tlv; - if(cqi_ri_info_rel13->tl.length == 0) - { - cqi_ri_info_rel13->report_type = NFAPI_CSI_REPORT_TYPE_APERIODIC; - } - else - { - cqi_ri_info_rel13->report_type = NFAPI_CSI_REPORT_TYPE_PERIODIC; - if(pull16(ppReadPackedMsg, &cqi_ri_info_rel13->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2, end) == 0) - return 0; - } - return 1; -} -static uint8_t unpack_ul_config_cqi_init_tx_params_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_initial_transmission_parameters_rel8_t* init_tx_params_rel8 = (nfapi_ul_config_initial_transmission_parameters_rel8_t*)tlv; - - return (pull8(ppReadPackedMsg, &init_tx_params_rel8->n_srs_initial, end) && - pull8(ppReadPackedMsg, &init_tx_params_rel8->initial_number_of_resource_blocks, end)); -} -static uint8_t unpack_ul_config_ulsch_harq_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_harq_information_rel10_t* harq_info_rel10 = (nfapi_ul_config_ulsch_harq_information_rel10_t*)tlv; - - return (pull8(ppReadPackedMsg, &harq_info_rel10->harq_size, end) && - pull8(ppReadPackedMsg, &harq_info_rel10->delta_offset_harq, end) && - pull8(ppReadPackedMsg, &harq_info_rel10->ack_nack_mode, end)); -} - -static uint8_t unpack_ul_config_ulsch_harq_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_ulsch_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_ulsch_harq_information_rel13_t*)tlv; - - return (pull16(ppReadPackedMsg, &harq_info_rel13->harq_size_2, end) && - pull8(ppReadPackedMsg, &harq_info_rel13->delta_offset_harq_2, end)); -} - -static uint8_t unpack_ul_config_ue_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_ue_information_rel8_t* ue_info_rel8 = (nfapi_ul_config_ue_information_rel8_t*)tlv; - - return (pull32(ppReadPackedMsg, &ue_info_rel8->handle, end) && - pull16(ppReadPackedMsg, (uint16_t *)&ue_info_rel8->rnti, end)); -} -static uint8_t unpack_ul_config_ue_info_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_ue_information_rel11_t* ue_info_rel11 = (nfapi_ul_config_ue_information_rel11_t*)tlv; - - return (pull8(ppReadPackedMsg, &ue_info_rel11->virtual_cell_id_enabled_flag, end) && - pull16(ppReadPackedMsg, &ue_info_rel11->npusch_identity, end)); -} -static uint8_t unpack_ul_config_ue_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_ue_information_rel13_t* ue_info_rel13 = (nfapi_ul_config_ue_information_rel13_t*)tlv; - - return (pull8(ppReadPackedMsg, &ue_info_rel13->ue_type, end) && - pull8(ppReadPackedMsg, &ue_info_rel13->empty_symbols, end) && - pull16(ppReadPackedMsg, &ue_info_rel13->total_number_of_repetitions, end) && - pull16(ppReadPackedMsg, &ue_info_rel13->repetition_number, end)); -} - -static uint8_t unpack_ul_config_cqi_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_information_rel8_t* cqi_info_rel8 = (nfapi_ul_config_cqi_information_rel8_t*)tlv; - - return ( pull16(ppReadPackedMsg, &cqi_info_rel8->pucch_index, end) && - pull8(ppReadPackedMsg, &cqi_info_rel8->dl_cqi_pmi_size, end)); -} -static uint8_t unpack_ul_config_cqi_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_information_rel10_t* cqi_info_rel10 = (nfapi_ul_config_cqi_information_rel10_t*)tlv; - - return (pull8(ppReadPackedMsg, &cqi_info_rel10->number_of_pucch_resource, end) && - pull16(ppReadPackedMsg, &cqi_info_rel10->pucch_index_p1, end)); -} -static uint8_t unpack_ul_config_cqi_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_cqi_information_rel13_t* cqi_info_rel13 = (nfapi_ul_config_cqi_information_rel13_t*)tlv; - - return (pull8(ppReadPackedMsg, &cqi_info_rel13->csi_mode, end) && - pull16(ppReadPackedMsg, &cqi_info_rel13->dl_cqi_pmi_size_2, end) && - pull8(ppReadPackedMsg, &cqi_info_rel13->starting_prb, end) && - pull8(ppReadPackedMsg, &cqi_info_rel13->n_prb, end) && - pull8(ppReadPackedMsg, &cqi_info_rel13->cdm_index, end) && - pull8(ppReadPackedMsg, &cqi_info_rel13->n_srs, end)); -} - -static uint8_t unpack_ul_config_sr_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_sr_information_rel8_t* sr_info_rel8 = (nfapi_ul_config_sr_information_rel8_t*)tlv; - - return ( pull16(ppReadPackedMsg, &sr_info_rel8->pucch_index, end)); -} - -static uint8_t unpack_ul_config_sr_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_sr_information_rel10_t* sr_info_rel10 = (nfapi_ul_config_sr_information_rel10_t*)tlv; - - return (pull8(ppReadPackedMsg, &sr_info_rel10->number_of_pucch_resources, end) && - pull16(ppReadPackedMsg, &sr_info_rel10->pucch_index_p1, end)); -} - -static uint8_t unpack_ul_config_harq_info_rel10_tdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_harq_information_rel10_tdd_t* harq_info_tdd_rel10 = (nfapi_ul_config_harq_information_rel10_tdd_t*)tlv; - - return (pull8(ppReadPackedMsg, &harq_info_tdd_rel10->harq_size, end) && - pull8(ppReadPackedMsg, &harq_info_tdd_rel10->ack_nack_mode, end) && - pull8(ppReadPackedMsg, &harq_info_tdd_rel10->number_of_pucch_resources, end) && - pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_0, end) && - pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_1, end) && - pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_2, end) && - pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_3, end)); -} - -static uint8_t unpack_ul_config_harq_info_rel8_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_harq_information_rel8_fdd_t* harq_info_fdd_rel8 = (nfapi_ul_config_harq_information_rel8_fdd_t*)tlv; - - return (pull16(ppReadPackedMsg, &harq_info_fdd_rel8->n_pucch_1_0, end) && - pull8(ppReadPackedMsg, &harq_info_fdd_rel8->harq_size, end)); -} - -static uint8_t unpack_ul_config_harq_info_rel9_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_harq_information_rel9_fdd_t* harq_info_fdd_rel9 = (nfapi_ul_config_harq_information_rel9_fdd_t*)tlv; - - return (pull8(ppReadPackedMsg, &harq_info_fdd_rel9->harq_size, end) && - pull8(ppReadPackedMsg, &harq_info_fdd_rel9->ack_nack_mode, end) && - pull8(ppReadPackedMsg, &harq_info_fdd_rel9->number_of_pucch_resources, end) && - pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_0, end) && - pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_1, end) && - pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_2, end) && - pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_3, end)); -} - -static uint8_t unpack_ul_config_harq_info_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_harq_information_rel11_t* harq_info_rel11 = (nfapi_ul_config_harq_information_rel11_t*)tlv; - - return (pull8(ppReadPackedMsg, &harq_info_rel11->num_ant_ports, end) && - pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_0, end) && - pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_1, end) && - pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_2, end) && - pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_3, end)); -} - -static uint8_t unpack_ul_config_harq_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_harq_information_rel13_t*)tlv; - - return (pull16(ppReadPackedMsg, &harq_info_rel13->harq_size_2, end) && - pull8(ppReadPackedMsg, &harq_info_rel13->starting_prb, end) && - pull8(ppReadPackedMsg, &harq_info_rel13->n_prb, end) && - pull8(ppReadPackedMsg, &harq_info_rel13->cdm_index, end) && - pull8(ppReadPackedMsg, &harq_info_rel13->n_srs, end)); -} - - -static uint8_t unpack_ul_config_srs_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_srs_pdu_rel8_t* srs_pdu_rel8 = (nfapi_ul_config_srs_pdu_rel8_t*)tlv; - - return (pull32(ppReadPackedMsg, &srs_pdu_rel8->handle, end) && - pull16(ppReadPackedMsg, &srs_pdu_rel8->size, end) && - pull16(ppReadPackedMsg, &srs_pdu_rel8->rnti, end) && - pull8(ppReadPackedMsg, &srs_pdu_rel8->srs_bandwidth, end) && - pull8(ppReadPackedMsg, &srs_pdu_rel8->frequency_domain_position, end) && - pull8(ppReadPackedMsg, &srs_pdu_rel8->srs_hopping_bandwidth, end) && - pull8(ppReadPackedMsg, &srs_pdu_rel8->transmission_comb, end) && - pull16(ppReadPackedMsg, &srs_pdu_rel8->i_srs, end) && - pull8(ppReadPackedMsg, &srs_pdu_rel8->sounding_reference_cyclic_shift, end)); -} - -static uint8_t unpack_ul_config_srs_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_srs_pdu_rel10_t* srs_pdu_rel10 = (nfapi_ul_config_srs_pdu_rel10_t*)tlv; - return pull8(ppReadPackedMsg, &srs_pdu_rel10->antenna_port, end); -} - -static uint8_t unpack_ul_config_srs_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_srs_pdu_rel13_t* srs_pdu_rel13 = (nfapi_ul_config_srs_pdu_rel13_t*)tlv; - - return (pull8(ppReadPackedMsg, &srs_pdu_rel13->number_of_combs, end)); -} - -static uint8_t unpack_ul_nb_harq_info_rel13_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_nb_harq_information_rel13_fdd_t* nb_harq_info_fdd_rel13 = (nfapi_ul_config_nb_harq_information_rel13_fdd_t*)tlv; - - return (pull8(ppReadPackedMsg, &nb_harq_info_fdd_rel13->harq_ack_resource, end)); -} - -static uint8_t unpack_ul_config_nulsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_nulsch_pdu_rel13_t* nulsch_pdu_rel13 = (nfapi_ul_config_nulsch_pdu_rel13_t*)tlv; - - if(!(pull8(ppReadPackedMsg, &nulsch_pdu_rel13->nulsch_format, end) && - pull32(ppReadPackedMsg, &nulsch_pdu_rel13->handle, end) && - pull16(ppReadPackedMsg, &nulsch_pdu_rel13->size, end) && - pull16(ppReadPackedMsg, &nulsch_pdu_rel13->rnti, end) && - pull8(ppReadPackedMsg, &nulsch_pdu_rel13->subcarrier_indication, end) && - pull8(ppReadPackedMsg, &nulsch_pdu_rel13->resource_assignment, end) && - pull8(ppReadPackedMsg, &nulsch_pdu_rel13->mcs, end) && - pull8(ppReadPackedMsg, &nulsch_pdu_rel13->redudancy_version, end) && - pull8(ppReadPackedMsg, &nulsch_pdu_rel13->repetition_number, end) && - pull8(ppReadPackedMsg, &nulsch_pdu_rel13->new_data_indication, end) && - pull8(ppReadPackedMsg, &nulsch_pdu_rel13->n_srs, end) && - pull16(ppReadPackedMsg, &nulsch_pdu_rel13->scrambling_sequence_initialization_cinit, end) && - pull16(ppReadPackedMsg, &nulsch_pdu_rel13->sf_idx, end))) - return 0; - - unpack_tlv_t unpack_fns[] = - { - { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel8, &unpack_ul_config_ue_info_rel8_value}, - { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel11, &unpack_ul_config_ue_info_rel11_value}, - { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel13, &unpack_ul_config_ue_info_rel13_value}, - { NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG, &nulsch_pdu_rel13->nb_harq_information.nb_harq_information_rel13_fdd, &unpack_ul_nb_harq_info_rel13_fdd_value}, - }; - - return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, 0, 0); -} - -static uint8_t unpack_ul_config_nrach_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_config_nrach_pdu_rel13_t* nrach_pdu_rel13 = (nfapi_ul_config_nrach_pdu_rel13_t*)tlv; - - return (pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_0, end) && - pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_1, end) && - pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_2, end)); -} - - -static uint8_t unpack_ul_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - #define UL_CONFIG_ULSCH_PDU_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &_pdu.ulsch_pdu_rel8, &unpack_ul_config_ulsch_pdu_rel8_value}, \ - { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &_pdu.ulsch_pdu_rel10, &unpack_ul_config_ulsch_pdu_rel10_value}, \ - { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG, &_pdu.ulsch_pdu_rel11, &unpack_ul_config_ulsch_pdu_rel11_value}, \ - { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG, &_pdu.ulsch_pdu_rel13, &unpack_ul_config_ulsch_pdu_rel13_value}, - - #define UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG, &_pdu.cqi_ri_information_rel8, &unpack_ul_config_cqi_ri_info_rel8_value}, \ - { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG, &_pdu.cqi_ri_information_rel9, &unpack_ul_config_cqi_ri_info_rel9_value}, \ - { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG, &_pdu.cqi_ri_information_rel13, &unpack_ul_config_cqi_ri_info_rel13_value}, - - #define UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG, &_pdu.harq_information_rel10, &unpack_ul_config_ulsch_harq_info_rel10_value},\ - { NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG, &_pdu.harq_information_rel13, &unpack_ul_config_ulsch_harq_info_rel13_value}, - - #define UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG, &_pdu.initial_transmission_parameters_rel8, &unpack_ul_config_cqi_init_tx_params_rel8_value}, - - #define UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &_pdu.ue_information_rel8, &unpack_ul_config_ue_info_rel8_value}, \ - { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &_pdu.ue_information_rel11, &unpack_ul_config_ue_info_rel11_value}, \ - { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &_pdu.ue_information_rel13, &unpack_ul_config_ue_info_rel13_value}, - - #define UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG, &_pdu.cqi_information_rel8, &unpack_ul_config_cqi_info_rel8_value}, \ - { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG, &_pdu.cqi_information_rel10, &unpack_ul_config_cqi_info_rel10_value}, \ - { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG, &_pdu.cqi_information_rel13, &unpack_ul_config_cqi_info_rel13_value}, - - #define UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG, &_pdu.sr_information_rel8, &unpack_ul_config_sr_info_rel8_value}, \ - { NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG, &_pdu.sr_information_rel10, &unpack_ul_config_sr_info_rel10_value}, - - #define UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG, &_pdu.harq_information_rel10_tdd, &unpack_ul_config_harq_info_rel10_tdd_value}, \ - { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG, &_pdu.harq_information_rel8_fdd, &unpack_ul_config_harq_info_rel8_fdd_value}, \ - { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG, &_pdu.harq_information_rel9_fdd, &unpack_ul_config_harq_info_rel9_fdd_value}, \ - { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG, &_pdu.harq_information_rel11, &unpack_ul_config_harq_info_rel11_value}, \ - { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG, &_pdu.harq_information_rel13, &unpack_ul_config_harq_info_rel13_value}, - - #define UL_CONFIG_SRS_PDU_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG, &_pdu.srs_pdu_rel8, &unpack_ul_config_srs_pdu_rel8_value}, \ - { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG, &_pdu.srs_pdu_rel10, &unpack_ul_config_srs_pdu_rel10_value}, \ - { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG, &_pdu.srs_pdu_rel13, &unpack_ul_config_srs_pdu_rel13_value}, - - #define UL_CONFIG_NULSCH_PDU_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG, &_pdu.nulsch_pdu_rel13, &unpack_ul_config_nulsch_pdu_rel13_value}, - - #define UL_CONFIG_NRACH_PDU_UNPACK_FNS(_pdu) \ - { NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG, &_pdu.nrach_pdu_rel13, &unpack_ul_config_nrach_pdu_rel13_value}, - - - nfapi_ul_config_request_body_t* value = (nfapi_ul_config_request_body_t*)tlv; - - if(!(pull8(ppReadPackedMsg, &value->number_of_pdus, end) && - pull8(ppReadPackedMsg, &value->rach_prach_frequency_resources, end) && - pull8(ppReadPackedMsg, &value->srs_present, end))) - return 0; - - if(value->number_of_pdus > NFAPI_UL_CONFIG_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of ul config pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_UL_CONFIG_MAX_PDU); - return 0; - } - - if(value->number_of_pdus > 0) - { - value->ul_config_pdu_list = (nfapi_ul_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_ul_config_request_pdu_t) * value->number_of_pdus, config); - - if(value->ul_config_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate ul config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); - return 0; - } - } - else - { - value->ul_config_pdu_list = 0; - } - - - uint16_t i; - uint16_t total_number_of_pdus = value->number_of_pdus; - for(i = 0; i < total_number_of_pdus; ++i) - { - nfapi_ul_config_request_pdu_t* pdu = &(value->ul_config_pdu_list[i]); - - if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && - pull8(ppReadPackedMsg, &pdu->pdu_size, end))) - return 0; - - uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; - - if(packedPduEnd > end) - { - // pdu end is past buffer end - return 0; - } - - switch(pdu->pdu_type) - { - case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_pdu) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - - case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.ulsch_pdu) - UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.cqi_ri_information) - UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.initial_transmission_parameters) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_harq_pdu.ulsch_pdu) - UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(pdu->ulsch_harq_pdu.harq_information) - UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_harq_pdu.initial_transmission_parameters) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu) - UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information) - UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.harq_information) - UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_pdu.ue_information) - UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_pdu.cqi_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_sr_pdu.ue_information) - UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_sr_pdu.sr_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_harq_pdu.ue_information) - UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_harq_pdu.harq_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.ue_information) - UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.sr_information) - UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.harq_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.ue_information) - UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.cqi_information) - UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.harq_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.ue_information) - UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.cqi_information) - UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.sr_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.ue_information) - UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.cqi_information) - UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.sr_information) - UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.harq_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_SRS_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_SRS_PDU_UNPACK_FNS(pdu->srs_pdu) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->harq_buffer_pdu.ue_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_uci_csi_pdu.ulsch_pdu) - UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->ulsch_uci_csi_pdu.csi_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_uci_harq_pdu.ulsch_pdu) - UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->ulsch_uci_harq_pdu.harq_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu) - UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.csi_information) - UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.harq_information) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_NULSCH_PDU_UNPACK_FNS(pdu->nulsch_pdu) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - UL_CONFIG_NRACH_PDU_UNPACK_FNS(pdu->nrach_pdu) - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - } - } - return 1; -} - - -static uint8_t unpack_ul_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_UL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->ul_config_request_body, &unpack_ul_config_request_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_hi_dci0_hi_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_hi_pdu_rel8_t* hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t*)tlv; - - return( pull8(ppReadPackedMsg, &hi_pdu_rel8->resource_block_start, end) && - pull8(ppReadPackedMsg, &hi_pdu_rel8->cyclic_shift_2_for_drms, end) && - pull8(ppReadPackedMsg, &hi_pdu_rel8->hi_value, end) && - pull8(ppReadPackedMsg, &hi_pdu_rel8->i_phich, end) && - pull16(ppReadPackedMsg, &hi_pdu_rel8->transmission_power, end)); -} - -static uint8_t unpack_hi_dci0_hi_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_hi_pdu_rel10_t* hi_pdu_rel10 = (nfapi_hi_dci0_hi_pdu_rel10_t*)tlv; - - return (pull8(ppReadPackedMsg, &hi_pdu_rel10->flag_tb2, end) && - pull8(ppReadPackedMsg, &hi_pdu_rel10->hi_value_2, end)); -} - -static uint8_t unpack_hi_dci0_dci_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_dci_pdu_rel8_t* dci_pdu_rel8 = (nfapi_hi_dci0_dci_pdu_rel8_t*)tlv; - - return (pull8(ppReadPackedMsg, &dci_pdu_rel8->dci_format, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->cce_index, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->aggregation_level, end) && - pull16(ppReadPackedMsg, &dci_pdu_rel8->rnti, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->resource_block_start, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->number_of_resource_block, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->mcs_1, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->cyclic_shift_2_for_drms, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->frequency_hopping_enabled_flag, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->frequency_hopping_bits, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->new_data_indication_1, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->ue_tx_antenna_seleciton, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->tpc, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->cqi_csi_request, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->ul_index, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel8->dl_assignment_index, end) && - pull32(ppReadPackedMsg, &dci_pdu_rel8->tpc_bitmap, end) && - pull16(ppReadPackedMsg, &dci_pdu_rel8->transmission_power, end)); -} - -static uint8_t unpack_hi_dci0_dci_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_dci_pdu_rel10_t* dci_pdu_rel10 = (nfapi_hi_dci0_dci_pdu_rel10_t*)tlv; - - return (pull8(ppReadPackedMsg, &dci_pdu_rel10->cross_carrier_scheduling_flag, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->carrier_indicator, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->size_of_cqi_csi_feild, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->srs_flag, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->srs_request, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->resource_allocation_flag, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->resource_allocation_type, end) && - pull32(ppReadPackedMsg, &dci_pdu_rel10->resource_block_coding, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->mcs_2, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->new_data_indication_2, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->number_of_antenna_ports, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->tpmi, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->total_dci_length_including_padding, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel10->n_ul_rb, end)); -} - -static uint8_t unpack_hi_dci0_dci_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_dci_pdu_rel12_t* dci_pdu_rel12 = (nfapi_hi_dci0_dci_pdu_rel12_t*)tlv; - - return ( pull8(ppReadPackedMsg, &dci_pdu_rel12->pscch_resource, end) && - pull8(ppReadPackedMsg, &dci_pdu_rel12->time_resource_pattern, end)); -} - -static uint8_t unpack_hi_dci0_mpdcch_dci_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t* value = (nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t*)tlv; - - return (pull8(ppReadPackedMsg, &value->mpdcch_narrowband, end) && - pull8(ppReadPackedMsg, &value->number_of_prb_pairs, end) && - pull8(ppReadPackedMsg, &value->resource_block_assignment, end) && - pull8(ppReadPackedMsg, &value->mpdcch_transmission_type, end) && - pull8(ppReadPackedMsg, &value->start_symbol, end) && - pull8(ppReadPackedMsg, &value->ecce_index, end) && - pull8(ppReadPackedMsg, &value->aggreagation_level, end) && - pull8(ppReadPackedMsg, &value->rnti_type, end) && - pull16(ppReadPackedMsg, &value->rnti, end) && - pull8(ppReadPackedMsg, &value->ce_mode, end) && - pull16(ppReadPackedMsg, &value->drms_scrambling_init, end) && - pull16(ppReadPackedMsg, &value->initial_transmission_sf_io, end) && - pull16(ppReadPackedMsg, &value->transmission_power, end) && - pull8(ppReadPackedMsg, &value->dci_format, end) && - pull8(ppReadPackedMsg, &value->resource_block_start, end) && - pull8(ppReadPackedMsg, &value->number_of_resource_blocks, end) && - pull8(ppReadPackedMsg, &value->mcs, end) && - pull8(ppReadPackedMsg, &value->pusch_repetition_levels, end) && - pull8(ppReadPackedMsg, &value->frequency_hopping_flag, end) && - pull8(ppReadPackedMsg, &value->new_data_indication, end) && - pull8(ppReadPackedMsg, &value->harq_process, end) && - pull8(ppReadPackedMsg, &value->redudency_version, end) && - pull8(ppReadPackedMsg, &value->tpc, end) && - pull8(ppReadPackedMsg, &value->csi_request, end) && - pull8(ppReadPackedMsg, &value->ul_inex, end) && - pull8(ppReadPackedMsg, &value->dai_presence_flag, end) && - pull8(ppReadPackedMsg, &value->dl_assignment_index, end) && - pull8(ppReadPackedMsg, &value->srs_request, end) && - pull8(ppReadPackedMsg, &value->dci_subframe_repetition_number, end) && - pull32(ppReadPackedMsg, &value->tcp_bitmap, end) && - pull8(ppReadPackedMsg, &value->total_dci_length_include_padding, end) && - pull8(ppReadPackedMsg, &value->number_of_tx_antenna_ports, end) && - pullarray16(ppReadPackedMsg, value->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, value->number_of_tx_antenna_ports, end)); -} - -static uint8_t unpack_hi_dci0_npdcch_dci_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_hi_dci0_npdcch_dci_pdu_rel13_t* value = (nfapi_hi_dci0_npdcch_dci_pdu_rel13_t*)tlv; - - return (pull8(ppReadPackedMsg, &value->ncce_index, end) && - pull8(ppReadPackedMsg, &value->aggregation_level, end) && - pull8(ppReadPackedMsg, &value->start_symbol, end) && - pull16(ppReadPackedMsg, &value->rnti, end) && - pull8(ppReadPackedMsg, &value->scrambling_reinitialization_batch_index, end) && - pull8(ppReadPackedMsg, &value->nrs_antenna_ports_assumed_by_the_ue, end) && - pull8(ppReadPackedMsg, &value->subcarrier_indication, end) && - pull8(ppReadPackedMsg, &value->resource_assignment, end) && - pull8(ppReadPackedMsg, &value->scheduling_delay, end) && - pull8(ppReadPackedMsg, &value->mcs, end) && - pull8(ppReadPackedMsg, &value->redudancy_version, end) && - pull8(ppReadPackedMsg, &value->repetition_number, end) && - pull8(ppReadPackedMsg, &value->new_data_indicator, end) && - pull8(ppReadPackedMsg, &value->dci_subframe_repetition_number, end)); -} - -static uint8_t unpack_hi_dci0_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_hi_dci0_request_body_t* value = (nfapi_hi_dci0_request_body_t*)tlv; - - if(!(pull16(ppReadPackedMsg, &value->sfnsf, end) && - pull8(ppReadPackedMsg, &value->number_of_dci, end) && - pull8(ppReadPackedMsg, &value->number_of_hi, end))) - return 0; - - uint8_t totalNumPdus = value->number_of_hi + value->number_of_dci; - - if(totalNumPdus > NFAPI_HI_DCI0_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of dci0 pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, totalNumPdus, NFAPI_HI_DCI0_MAX_PDU); - return 0; - } - - if(totalNumPdus > 0) - { - value->hi_dci0_pdu_list = (nfapi_hi_dci0_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_hi_dci0_request_pdu_t) * totalNumPdus, config); - if(value->hi_dci0_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate hi dci0 pdu list (count:%d)\n", __FUNCTION__, totalNumPdus); - return 0; - } - } - else - { - value->hi_dci0_pdu_list = 0; - } - - uint8_t i; - for(i = 0; i < totalNumPdus; ++i) - { - nfapi_hi_dci0_request_pdu_t* pdu = &(value->hi_dci0_pdu_list[i]); - - if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && - pull8(ppReadPackedMsg, &pdu->pdu_size, end))) - return 0; - - uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; - - if(packedPduEnd > end) - { - // pdu end if past buffer end - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pdu size to big %d %d\n", __FUNCTION__, packedPduEnd, end); - return 0; - } - - switch(pdu->pdu_type) - { - case NFAPI_HI_DCI0_HI_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG, &pdu->hi_pdu.hi_pdu_rel8, &unpack_hi_dci0_hi_pdu_rel8_value}, - { NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG, &pdu->hi_pdu.hi_pdu_rel10, &unpack_hi_dci0_hi_pdu_rel10_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_HI_DCI0_DCI_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG, &pdu->dci_pdu.dci_pdu_rel8, &unpack_hi_dci0_dci_pdu_rel8_value}, - { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG, &pdu->dci_pdu.dci_pdu_rel10, &unpack_hi_dci0_dci_pdu_rel10_value}, - { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG, &pdu->dci_pdu.dci_pdu_rel12, &unpack_hi_dci0_dci_pdu_rel12_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel8, &unpack_hi_dci0_dci_pdu_rel8_value}, - { NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel10, &unpack_hi_dci0_dci_pdu_rel10_value}, - { NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG, &pdu->epdcch_dci_pdu.epdcch_parameters_rel11, &unpack_dl_config_epdcch_params_rel11_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG, &pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13, &unpack_hi_dci0_mpdcch_dci_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG, &pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13, &unpack_hi_dci0_npdcch_dci_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); - } - break; - }; - } - - return 1; -} - -static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_HI_DCI0_REQUEST_BODY_TAG, &pNfapiMsg->hi_dci0_request_body, &unpack_hi_dci0_request_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); - -} - -static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - uint8_t proceed = 1; - nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t*)msg; - - if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0) - return 0; - - while (((uint8_t*)(*ppReadPackedMsg) < end) && proceed) - { - nfapi_tl_t generic_tl; - if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) - return 0; - - switch(generic_tl.tag) - { - case NFAPI_TX_REQUEST_BODY_TAG: - { - pNfapiMsg->tx_request_body.tl = generic_tl; - - if( pull16(ppReadPackedMsg, &pNfapiMsg->tx_request_body.number_of_pdus, end) == 0) - return 0; - - if(pNfapiMsg->tx_request_body.number_of_pdus > NFAPI_TX_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of tx pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->tx_request_body.number_of_pdus, NFAPI_TX_MAX_PDU); - return 0; - } - - if(pNfapiMsg->tx_request_body.number_of_pdus > 0) - { - pNfapiMsg->tx_request_body.tx_pdu_list = (nfapi_tx_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_tx_request_pdu_t) * pNfapiMsg->tx_request_body.number_of_pdus, config); - if(pNfapiMsg->tx_request_body.tx_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate tx pdu list (count:%d)\n", __FUNCTION__, pNfapiMsg->tx_request_body.number_of_pdus); - return 0; - } - } - else - { - pNfapiMsg->tx_request_body.tx_pdu_list = 0; - } - - - uint16_t i; - uint16_t totalNumPdus = pNfapiMsg->tx_request_body.number_of_pdus; - for(i = 0; i < totalNumPdus; ++i) - { - nfapi_tx_request_pdu_t* pdu = &(pNfapiMsg->tx_request_body.tx_pdu_list[i]); + case NFAPI_HARQ_INDICATION: + result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_CRC_INDICATION: + result = pack_crc_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RX_ULSCH_INDICATION: + //printf("RX ULSCH\n"); + result = pack_rx_ulsch_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RACH_INDICATION: + result = pack_rach_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_SRS_INDICATION: + result = pack_srs_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RX_SR_INDICATION: + result = pack_sr_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RX_CQI_INDICATION: + result = pack_cqi_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_LBT_DL_CONFIG_REQUEST: + result = pack_lbt_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_LBT_DL_INDICATION: + result = pack_lbt_dl_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NB_HARQ_INDICATION: + result = pack_nb_harq_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NRACH_INDICATION: + result = pack_nrach_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC: + result = pack_nr_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC: + result = pack_nr_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_TIMING_INFO: + result = pack_nr_timing_info(pMessageHeader, &pWritePackedMessage, end, config); + break; + + default: + { + if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->pack_p7_vendor_extension) + { + result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, pMessageHeader->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + } + break; + } + + if(result == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n"); + return -1; + } + + // check for a valid message length + uintptr_t msgHead = (uintptr_t)pPackedBuf; + uintptr_t msgEnd = (uintptr_t)pWritePackedMessage; + uint32_t packedMsgLen = msgEnd - msgHead; + uint16_t packedMsgLen16; + if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen); + return -1; + } + else + { + packedMsgLen16 = (uint16_t)packedMsgLen; + } + + // Update the message length in the header + pMessageHeader->message_length = packedMsgLen16; + + if(!push16(packedMsgLen16, &pPackedLengthField, end)) + return -1; + + if(1) + { + //quick test + if(pMessageHeader->message_length != packedMsgLen) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", packedMsgLen, pMessageHeader->message_length, pMessageHeader->message_id); + } + } + + return (packedMsgLen); +} + +int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config) +{ + nfapi_p7_message_header_t *pMessageHeader = pMessageBuf; + uint8_t *pWritePackedMessage = pPackedBuf; + uint8_t *pPackedLengthField = &pWritePackedMessage[4]; + uint8_t *end = pPackedBuf + packedBufLen; + + if (pMessageBuf == NULL || pPackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n"); + return -1; + } + /* + printf("\n P7 MESSAGE SENT: \n"); + for(int i=0; i< packedBufLen; i++){ + printf("%d", *(uint8_t *)(pMessageBuf + i)); + } + printf("\n"); + */ + // process the header + if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && + push16(pMessageHeader->message_id, &pWritePackedMessage, end) && + push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) && + push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end) && + push32(0/*pMessageHeader->checksum*/, &pWritePackedMessage, end) && + push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end))) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n"); + return -1; + } + + if (pMessageHeader->message_id != NFAPI_TIMING_INFO) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__, pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp); + } + // look for the specific message + uint8_t result = 0; + switch (pMessageHeader->message_id) + { + case NFAPI_DL_CONFIG_REQUEST: + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_DL_CONFIG_REQUEST\n", __FUNCTION__); + result = pack_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_UL_CONFIG_REQUEST: + result = pack_ul_config_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + case NFAPI_TX_REQUEST: + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__); + result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + case NFAPI_HI_DCI0_REQUEST: + result = pack_hi_dci0_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_UE_RELEASE_REQUEST: + result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_UE_RELEASE_RESPONSE: + result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_HARQ_INDICATION: + result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_CRC_INDICATION: + result = pack_crc_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RX_ULSCH_INDICATION: + //printf("RX ULSCH\n"); + result = pack_rx_ulsch_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RACH_INDICATION: + result = pack_rach_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_SRS_INDICATION: + result = pack_srs_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RX_SR_INDICATION: + result = pack_sr_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_RX_CQI_INDICATION: + result = pack_cqi_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_LBT_DL_CONFIG_REQUEST: + result = pack_lbt_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_LBT_DL_INDICATION: + result = pack_lbt_dl_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NB_HARQ_INDICATION: + result = pack_nb_harq_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_NRACH_INDICATION: + result = pack_nrach_indication(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_DL_NODE_SYNC: + result = pack_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_UL_NODE_SYNC: + result = pack_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config); + break; + + case NFAPI_TIMING_INFO: + result = pack_timing_info(pMessageHeader, &pWritePackedMessage, end, config); + break; + + default: + { + if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->pack_p7_vendor_extension) + { + result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, pMessageHeader->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + } + break; + } + + if(result == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n"); + return -1; + } + + // check for a valid message length + uintptr_t msgHead = (uintptr_t)pPackedBuf; + uintptr_t msgEnd = (uintptr_t)pWritePackedMessage; + uint32_t packedMsgLen = msgEnd - msgHead; + uint16_t packedMsgLen16; + if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen); + return -1; + } + else + { + packedMsgLen16 = (uint16_t)packedMsgLen; + } + + // Update the message length in the header + pMessageHeader->message_length = packedMsgLen16; + + if(!push16(packedMsgLen16, &pPackedLengthField, end)) + return -1; + + if(1) + { + //quick test + if(pMessageHeader->message_length != packedMsgLen) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", packedMsgLen, pMessageHeader->message_length, pMessageHeader->message_id); + } + } + + return (packedMsgLen); +} + +// Unpack routines +// NR: +static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_csi_rs_pdu_rel15_t* value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t*)tlv; + + return( + pull16(ppReadPackedMsg, &value->bwp_size, end) && + pull16(ppReadPackedMsg, &value->bwp_start, end) && + + pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) && + pull8(ppReadPackedMsg, &value->cyclic_prefix, end) && + + pull16(ppReadPackedMsg, &value->start_rb, end) && + pull16(ppReadPackedMsg, &value->nr_of_rbs, end) && + + pull8(ppReadPackedMsg, &value->csi_type, end) && + pull8(ppReadPackedMsg, &value->row, end) && + + pull16(ppReadPackedMsg, &value->freq_domain, end) && + pull8(ppReadPackedMsg, &value->symb_l0, end) && + + pull8(ppReadPackedMsg, &value->symb_l1, end) && + pull8(ppReadPackedMsg, &value->cdm_type, end) && + + pull8(ppReadPackedMsg, &value->freq_density, end) && + pull16(ppReadPackedMsg, &value->scramb_id, end) && + + pull8(ppReadPackedMsg, &value->power_control_offset, end) && + pull8(ppReadPackedMsg, &value->power_control_offset_ss, end) + ); + +} + + +static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_pdcch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t*)tlv; + + for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) + { + if(!pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) && + pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end) && + + pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end) && + pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end) && + pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end) && + pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end) && + + pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end) && + pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end) && + + pullarray8(ppReadPackedMsg, value->dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->dci_pdu[i].PayloadSizeBits, end)); + + return 0; + } + + // TODO: resolve the packaging of array (currently sending a single element) + return( + pull16(ppReadPackedMsg, &value->BWPSize, end) && + pull16(ppReadPackedMsg, &value->BWPStart, end) && + pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) && + pull8(ppReadPackedMsg, &value->CyclicPrefix, end) && + + pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) && + pull8(ppReadPackedMsg, &value->DurationSymbols, end) && + pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end) && + pull8(ppReadPackedMsg, &value->CceRegMappingType, end) && + + pull8(ppReadPackedMsg, &value->RegBundleSize, end) && + pull8(ppReadPackedMsg, &value->InterleaverSize, end) && + pull8(ppReadPackedMsg, &value->CoreSetType, end) && + pull16(ppReadPackedMsg, &value->ShiftIndex, end) && + + pull8(ppReadPackedMsg, &value->precoderGranularity, end) && + pull16(ppReadPackedMsg, &value->numDlDci, end)); + +} + + +static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_pdsch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t*)tlv; + + // TODO: resolve the packaging of array (currently sending a single element) + return( + pull16(ppReadPackedMsg, &value->pduBitmap, end) && + pull16(ppReadPackedMsg, &value->rnti, end) && + pull16(ppReadPackedMsg, &value->pduIndex, end) && + pull16(ppReadPackedMsg, &value->BWPSize, end) && + + pull16(ppReadPackedMsg, &value->BWPStart, end) && + pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) && + pull8(ppReadPackedMsg, &value->CyclicPrefix, end) && + pull8(ppReadPackedMsg, &value->NrOfCodewords, end) && + + pullarray16(ppReadPackedMsg, value->targetCodeRate, 2, 1, end) && + pullarray8(ppReadPackedMsg, value->qamModOrder, 2, 1, end) && + pullarray8(ppReadPackedMsg, value->mcsIndex, 2, 1, end) && + pullarray8(ppReadPackedMsg, value->mcsTable, 2, 1, end) && + + pullarray8(ppReadPackedMsg, value->rvIndex, 2, 1, end) && + pullarray32(ppReadPackedMsg, value->TBSize, 2, 1, end) && + pull16(ppReadPackedMsg, &value->dataScramblingId, end) && + pull8(ppReadPackedMsg, &value->nrOfLayers, end) && + + pull8(ppReadPackedMsg, &value->transmissionScheme, end) && + pull8(ppReadPackedMsg, &value->refPoint, end) && + pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) && + pull8(ppReadPackedMsg, &value->dmrsConfigType, end) && + + pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) && + pull8(ppReadPackedMsg, &value->SCID, end) && + pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) && + pull16(ppReadPackedMsg, &value->dmrsPorts, end) && + + pull8(ppReadPackedMsg, &value->resourceAlloc, end) && + pull16(ppReadPackedMsg, &value->rbStart, end) && + pull16(ppReadPackedMsg, &value->rbSize, end) && + + pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) && + pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) && + pull8(ppReadPackedMsg, &value->NrOfSymbols, end) && + pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) && + + pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end) && + pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) && + pull8(ppReadPackedMsg, &value->PTRSReOffset, end) + ); + +} + + +static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_dl_tti_ssb_pdu_rel15_t* value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t*)tlv; + + return( + pull16(ppReadPackedMsg, &value->PhysCellId, end) && + pull8(ppReadPackedMsg, &value->BetaPss, end) && + pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) && + pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end) && + pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) && + pull8(ppReadPackedMsg, &value->bchPayloadFlag, end) && + pull32(ppReadPackedMsg, &value->bchPayload, end) + // TODO: pack precoding_and_beamforming too + ); + +} + + +// LTE: +static uint8_t unpack_dl_config_dci_dl_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel8_t* dci_dl_pdu_rel8 = (nfapi_dl_config_dci_dl_pdu_rel8_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->dci_format, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->cce_idx, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->aggregation_level, end) && + pull16(ppReadPackedMsg, &dci_dl_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->resource_allocation_type, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->virtual_resource_block_assignment_flag, end) && + pull32(ppReadPackedMsg, &dci_dl_pdu_rel8->resource_block_coding, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->mcs_1, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->redundancy_version_1, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->new_data_indicator_1, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->transport_block_to_codeword_swap_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->mcs_2, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->redundancy_version_2, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->new_data_indicator_2, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->harq_process, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->tpmi, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->pmi, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->precoding_information, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->tpc, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->downlink_assignment_index, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->ngap, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->transport_block_size_index, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->downlink_power_offset, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->allocate_prach_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->preamble_index, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->prach_mask_index, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel8->rnti_type, end) && + pull16(ppReadPackedMsg, &dci_dl_pdu_rel8->transmission_power, end)); + +} + +static uint8_t unpack_dl_config_dci_dl_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel9_t* dci_dl_pdu_rel9 = (nfapi_dl_config_dci_dl_pdu_rel9_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->mcch_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->mcch_change_notification, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel9->scrambling_identity, end)); +} + +static uint8_t unpack_dl_config_dci_dl_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel10_t* dci_dl_pdu_rel10 = (nfapi_dl_config_dci_dl_pdu_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->cross_carrier_scheduling_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->carrier_indicator, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->srs_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->srs_request, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->antenna_ports_scrambling_and_layers, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->total_dci_length_including_padding, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel10->n_dl_rb, end)); +} + +static uint8_t unpack_dl_config_dci_dl_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel11_t* dci_dl_pdu_rel11 = (nfapi_dl_config_dci_dl_pdu_rel11_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel11->harq_ack_resource_offset, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel11->pdsch_re_mapping_quasi_co_location_indicator, end)); +} + +static uint8_t unpack_dl_config_dci_dl_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel12_t* dci_dl_pdu_rel12 = (nfapi_dl_config_dci_dl_pdu_rel12_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->primary_cell_type, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->ul_dl_configuration_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel12->number_ul_dl_configurations, end) && + pullarray8(ppReadPackedMsg, dci_dl_pdu_rel12->ul_dl_configuration_indication, NFAPI_MAX_UL_DL_CONFIGURATIONS, dci_dl_pdu_rel12->number_ul_dl_configurations, end)); +} + +static uint8_t unpack_tpm_value(uint8_t **ppReadPackedMsg, nfapi_dl_config_dci_dl_tpm_t *value, uint8_t *end) +{ + if(!(pull8(ppReadPackedMsg, &value->num_prb_per_subband, end) && + pull8(ppReadPackedMsg, &value->number_of_subbands, end) && + pull8(ppReadPackedMsg, &value->num_antennas, end))) + return 0; + + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_subbands; ++idx) + { + nfapi_dl_config_dci_dl_tpm_subband_info_t* subband_info = &(value->subband_info[idx]); + + if(!(pull8(ppReadPackedMsg, &subband_info->subband_index, end) && + pull8(ppReadPackedMsg, &subband_info->scheduled_ues, end))) + return 0; + + uint8_t antenna_idx = 0; + uint8_t scheduled_ue_idx = 0; + + for(antenna_idx = 0; antenna_idx < value->num_antennas; ++antenna_idx) + { + for(scheduled_ue_idx = 0; scheduled_ue_idx < subband_info->scheduled_ues; ++scheduled_ue_idx) + { + if(!pull16(ppReadPackedMsg, &(subband_info->precoding_value[antenna_idx][scheduled_ue_idx]), end)) + return 0; + } + } + + } + + + return 1; + +} + + +static uint8_t unpack_dl_config_dci_dl_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dci_dl_pdu_rel13_t* dci_dl_pdu_rel13 = (nfapi_dl_config_dci_dl_pdu_rel13_t*)tlv; + + // If the length is greater than 5 then the TPM struct flag and possiably the TPM structure have been + // added + uint8_t tpm_struct_flag_present = dci_dl_pdu_rel13->tl.length > 5; + dci_dl_pdu_rel13->tpm_struct_flag = 0; + + return (pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->laa_end_partial_sf_flag, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->laa_end_partial_sf_configuration, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->initial_lbt_sf, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->codebook_size_determination, end) && + pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->drms_table_flag, end) && + ( (tpm_struct_flag_present == 1) ? pull8(ppReadPackedMsg, &dci_dl_pdu_rel13->tpm_struct_flag, end) : 1) && + ( (tpm_struct_flag_present == 1 && dci_dl_pdu_rel13->tpm_struct_flag == 1) ? unpack_tpm_value(ppReadPackedMsg, &dci_dl_pdu_rel13->tpm, end) : 1)); + +} + +static uint8_t unpack_dl_config_bch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_bch_pdu_rel8_t* bch_pdu_rel8 = (nfapi_dl_config_bch_pdu_rel8_t*)tlv; + + return ( pull16(ppReadPackedMsg, &bch_pdu_rel8->length, end) && + pull16(ppReadPackedMsg, (uint16_t *)&bch_pdu_rel8->pdu_index, end) && + pull16(ppReadPackedMsg, &bch_pdu_rel8->transmission_power, end)); +} + +static uint8_t unpack_dl_config_mch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_mch_pdu_rel8_t* mch_pdu_rel8 = (nfapi_dl_config_mch_pdu_rel8_t*)tlv; + + return (pull16(ppReadPackedMsg, &mch_pdu_rel8->length, end) && + pull16(ppReadPackedMsg, (uint16_t *)&mch_pdu_rel8->pdu_index, end) && + pull16(ppReadPackedMsg, &mch_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &mch_pdu_rel8->resource_allocation_type, end) && + pull32(ppReadPackedMsg, &mch_pdu_rel8->resource_block_coding, end) && + pull8(ppReadPackedMsg, &mch_pdu_rel8->modulation, end) && + pull16(ppReadPackedMsg, &mch_pdu_rel8->transmission_power, end) && + pull16(ppReadPackedMsg, &mch_pdu_rel8->mbsfn_area_id, end)); +} + +static uint8_t unpack_dl_config_dlsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel8_t* dlsch_pdu_rel8 = (nfapi_dl_config_dlsch_pdu_rel8_t*)tlv; + + if (!(pull16(ppReadPackedMsg, &dlsch_pdu_rel8->length, end) && + pull16(ppReadPackedMsg, (uint16_t *)&dlsch_pdu_rel8->pdu_index, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->resource_allocation_type, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->virtual_resource_block_assignment_flag, end) && + pull32(ppReadPackedMsg, &dlsch_pdu_rel8->resource_block_coding, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->modulation, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->redundancy_version, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transport_blocks, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transport_block_to_codeword_swap_flag, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transmission_scheme, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->number_of_layers, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->number_of_subbands, end) && + pullarray8(ppReadPackedMsg, dlsch_pdu_rel8->codebook_index, NFAPI_MAX_NUM_SUBBANDS, dlsch_pdu_rel8->number_of_subbands, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->ue_category_capacity, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->pa, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->delta_power_offset_index, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->ngap, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->nprb, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->transmission_mode, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->num_bf_prb_per_subband, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->num_bf_vector, end))) + return 0; + + uint16_t j = 0; + for(j = 0; j < dlsch_pdu_rel8->num_bf_vector; ++j) + { + if(!(pull8(ppReadPackedMsg, &dlsch_pdu_rel8->bf_vector[j].subband_index, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel8->bf_vector[j].num_antennas, end) && + pullarray16(ppReadPackedMsg, dlsch_pdu_rel8->bf_vector[j].bf_value, NFAPI_MAX_NUM_ANTENNAS, dlsch_pdu_rel8->bf_vector[j].num_antennas, end))) + return 0; + } + return 1; +} +static uint8_t unpack_dl_config_dlsch_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel9_t* dlsch_pdu_rel9 = (nfapi_dl_config_dlsch_pdu_rel9_t*)tlv; + return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel9->nscid, end) ); +} +static uint8_t unpack_dl_config_dlsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel10_t* dlsch_pdu_rel10 = (nfapi_dl_config_dlsch_pdu_rel10_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_flag, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_resource_config_r10, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_zero_tx_power_resource_config_bitmap_r10, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel10->csi_rs_number_nzp_configuration, end) && + pullarray8(ppReadPackedMsg, dlsch_pdu_rel10->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, dlsch_pdu_rel10->csi_rs_number_nzp_configuration, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel10->pdsch_start, end)) ; +} +static uint8_t unpack_dl_config_dlsch_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel11_t* dlsch_pdu_rel11 = (nfapi_dl_config_dlsch_pdu_rel11_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel11->drms_config_flag, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel11->drms_scrambling, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel11->csi_config_flag, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel11->csi_scrambling, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_flag, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_atenna_ports, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel11->pdsch_re_mapping_freq_shift, end)); +} +static uint8_t unpack_dl_config_dlsch_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel12_t* dlsch_pdu_rel12 = (nfapi_dl_config_dlsch_pdu_rel12_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel12->altcqi_table_r12, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel12->maxlayers, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel12->n_dl_harq, end)); +} +static uint8_t unpack_dl_config_dlsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_dlsch_pdu_rel13_t* dlsch_pdu_rel13 = (nfapi_dl_config_dlsch_pdu_rel13_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dlsch_pdu_rel13->dwpts_symbols, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel13->initial_lbt_sf, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel13->ue_type, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel13->pdsch_payload_type, end) && + pull16(ppReadPackedMsg, &dlsch_pdu_rel13->initial_transmission_sf_io, end) && + pull8(ppReadPackedMsg, &dlsch_pdu_rel13->drms_table_flag, end)); +} + +static uint8_t unpack_dl_config_pch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_pch_pdu_rel8_t* pch_pdu_rel8 = (nfapi_dl_config_pch_pdu_rel8_t*)tlv; + + return ( pull16(ppReadPackedMsg, &pch_pdu_rel8->length, end) && + pull16(ppReadPackedMsg, (uint16_t *)&pch_pdu_rel8->pdu_index, end) && + pull16(ppReadPackedMsg, &pch_pdu_rel8->p_rnti, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->resource_allocation_type, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->virtual_resource_block_assignment_flag, end) && + pull32(ppReadPackedMsg, &pch_pdu_rel8->resource_block_coding, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->mcs, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->redundancy_version, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->number_of_transport_blocks, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->transport_block_to_codeword_swap_flag, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->transmission_scheme, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->number_of_layers, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->codebook_index, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->ue_category_capacity, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->pa, end) && + pull16(ppReadPackedMsg, &pch_pdu_rel8->transmission_power, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->nprb, end) && + pull8(ppReadPackedMsg, &pch_pdu_rel8->ngap, end)); +} +static uint8_t unpack_dl_config_pch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_pch_pdu_rel13_t* pch_pdu_rel13 = (nfapi_dl_config_pch_pdu_rel13_t*)tlv; + + return ( pull8(ppReadPackedMsg, &pch_pdu_rel13->ue_mode, end) && + pull16(ppReadPackedMsg, &pch_pdu_rel13->initial_transmission_sf_io, end)); +} + +static uint8_t unpack_dl_config_prs_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_prs_pdu_rel9_t* prs_pdu_rel9 = (nfapi_dl_config_prs_pdu_rel9_t*)tlv; + + return ( pull16(ppReadPackedMsg, &prs_pdu_rel9->transmission_power, end) && + pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_bandwidth, end) && + pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_cyclic_prefix_type, end) && + pull8(ppReadPackedMsg, &prs_pdu_rel9->prs_muting, end)); +} + +static uint8_t unpack_dl_config_csi_rs_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_csi_rs_pdu_rel10_t* csi_rs_pdu_rel10 = (nfapi_dl_config_csi_rs_pdu_rel10_t*)tlv; + + return ( pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_antenna_port_count_r10, end) && + pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_resource_config_r10, end) && + pull16(ppReadPackedMsg, &csi_rs_pdu_rel10->transmission_power, end) && + pull16(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_zero_tx_power_resource_config_bitmap_r10, end) && + pull8(ppReadPackedMsg, &csi_rs_pdu_rel10->csi_rs_number_of_nzp_configuration, end) && + pullarray8(ppReadPackedMsg, csi_rs_pdu_rel10->csi_rs_resource_config, NFAPI_MAX_CSI_RS_RESOURCE_CONFIG, csi_rs_pdu_rel10->csi_rs_number_of_nzp_configuration, end)); +} + +static uint8_t unpack_dl_config_csi_rs_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_csi_rs_pdu_rel13_t* csi_rs_pdu_rel13 = (nfapi_dl_config_csi_rs_pdu_rel13_t*)tlv; + + if (!(pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->csi_rs_class, end) && + pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->cdm_type, end) && + pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->num_bf_vector, end))) + return 0; + + + uint16_t idx =0; + for(idx = 0; idx < csi_rs_pdu_rel13->num_bf_vector; ++idx) + { + if(!(pull8(ppReadPackedMsg, &csi_rs_pdu_rel13->bf_vector[idx].csi_rs_resource_index, end))) + return 0; + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : HOW TO DECODE BF VALUE \n"); + //pullarray16(ppReadPackedMsg, &csi_rs_pdu_rel13->bf_vector[idx].bf_vector, ??); + } + return 1; +} + +static uint8_t unpack_dl_config_epdcch_params_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_epdcch_parameters_rel11_t* epdcch_params_rel11 = (nfapi_dl_config_epdcch_parameters_rel11_t*)tlv; + + return (pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_resource_assignment_flag, end) && + pull16(ppReadPackedMsg, &epdcch_params_rel11->epdcch_id, end) && + pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_start_symbol, end) && + pull8(ppReadPackedMsg, &epdcch_params_rel11->epdcch_num_prb, end) && + pullarray8(ppReadPackedMsg, epdcch_params_rel11->epdcch_prb_index, NFAPI_MAX_EPDCCH_PRB, epdcch_params_rel11->epdcch_num_prb, end) && + pull8(ppReadPackedMsg, &epdcch_params_rel11->bf_vector.subband_index, end) && + pull8(ppReadPackedMsg, &epdcch_params_rel11->bf_vector.num_antennas, end) && + pullarray16(ppReadPackedMsg, epdcch_params_rel11->bf_vector.bf_value, NFAPI_MAX_NUM_ANTENNAS, epdcch_params_rel11->bf_vector.num_antennas, end)); +} + +static uint8_t unpack_dl_config_epdcch_params_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_epdcch_parameters_rel13_t* epdcch_params_rel13 = (nfapi_dl_config_epdcch_parameters_rel13_t*)tlv; + + return ( pull8(ppReadPackedMsg, &epdcch_params_rel13->dwpts_symbols, end) && + pull8(ppReadPackedMsg, &epdcch_params_rel13->initial_lbt_sf, end)); +} + +static uint8_t unpack_dl_config_mpdcch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_mpdcch_pdu_rel13_t* mpdcch_params_rel13 = (nfapi_dl_config_mpdcch_pdu_rel13_t*)tlv; + + + return ( pull8(ppReadPackedMsg, &mpdcch_params_rel13->mpdcch_narrow_band, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->number_of_prb_pairs, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->resource_block_assignment, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->mpdcch_tansmission_type, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->start_symbol, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->ecce_index, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->aggregation_level, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->rnti_type, end) && + pull16(ppReadPackedMsg, &mpdcch_params_rel13->rnti, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->ce_mode, end) && + pull16(ppReadPackedMsg, &mpdcch_params_rel13->drms_scrambling_init, end) && + pull16(ppReadPackedMsg, &mpdcch_params_rel13->initial_transmission_sf_io, end) && + pull16(ppReadPackedMsg, &mpdcch_params_rel13->transmission_power, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->dci_format, end) && + pull16(ppReadPackedMsg, &mpdcch_params_rel13->resource_block_coding, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->mcs, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->pdsch_reptition_levels, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->redundancy_version, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->new_data_indicator, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->harq_process, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpmi_length, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpmi, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->pmi_flag, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->pmi, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->harq_resource_offset, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->dci_subframe_repetition_number, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->tpc, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->downlink_assignment_index_length, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->downlink_assignment_index, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->allocate_prach_flag, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->preamble_index, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->prach_mask_index, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->starting_ce_level, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->srs_request, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->antenna_ports_and_scrambling_identity_flag, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->antenna_ports_and_scrambling_identity, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->frequency_hopping_enabled_flag, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->paging_direct_indication_differentiation_flag, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->direct_indication, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->total_dci_length_including_padding, end) && + pull8(ppReadPackedMsg, &mpdcch_params_rel13->number_of_tx_antenna_ports, end) && + pullarray16(ppReadPackedMsg, mpdcch_params_rel13->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, mpdcch_params_rel13->number_of_tx_antenna_ports, end)); +} + + +static uint8_t unpack_dl_config_nbch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_nbch_pdu_rel13_t* nbch_params_rel13 = (nfapi_dl_config_nbch_pdu_rel13_t*)tlv; + + return ( pull16(ppReadPackedMsg, &nbch_params_rel13->length, end) && + pull16(ppReadPackedMsg, (uint16_t *)&nbch_params_rel13->pdu_index, end) && + pull16(ppReadPackedMsg, &nbch_params_rel13->transmission_power, end) && + pull16(ppReadPackedMsg, &nbch_params_rel13->hyper_sfn_2_lsbs, end)); +} + +static uint8_t unpack_dl_config_npdcch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_npdcch_pdu_rel13_t* npdcch_params_rel13 = (nfapi_dl_config_npdcch_pdu_rel13_t*)tlv; + + return ( pull16(ppReadPackedMsg, &npdcch_params_rel13->length, end) && + pull16(ppReadPackedMsg, (uint16_t *)&npdcch_params_rel13->pdu_index, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->ncce_index, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->aggregation_level, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->start_symbol, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->rnti_type, end) && + pull16(ppReadPackedMsg, &npdcch_params_rel13->rnti, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->scrambling_reinitialization_batch_index, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->dci_format, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->scheduling_delay, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->resource_assignment, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->repetition_number, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->mcs, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->new_data_indicator, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->harq_ack_resource, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->npdcch_order_indication, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->starting_number_of_nprach_repetitions, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->subcarrier_indication_of_nprach, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->paging_direct_indication_differentation_flag, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->direct_indication, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->dci_subframe_repetition_number, end) && + pull8(ppReadPackedMsg, &npdcch_params_rel13->total_dci_length_including_padding, end)); +} + +static uint8_t unpack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_dl_config_ndlsch_pdu_rel13_t* ndlsch_params_rel13 = (nfapi_dl_config_ndlsch_pdu_rel13_t*)tlv; + + return ( pull16(ppReadPackedMsg, &ndlsch_params_rel13->length, end) && + pull16(ppReadPackedMsg, (uint16_t *)&ndlsch_params_rel13->pdu_index, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->start_symbol, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->rnti_type, end) && + pull16(ppReadPackedMsg, &ndlsch_params_rel13->rnti, end) && + pull16(ppReadPackedMsg, &ndlsch_params_rel13->resource_assignment, end) && + pull16(ppReadPackedMsg, &ndlsch_params_rel13->repetition_number, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->modulation, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->number_of_subframes_for_resource_assignment, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->scrambling_sequence_initialization_cinit, end) && + pull16(ppReadPackedMsg, &ndlsch_params_rel13->sf_idx, end) && + pull8(ppReadPackedMsg, &ndlsch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end)); +} + + +static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) +{ + nfapi_nr_dl_tti_request_pdu_t* value = (nfapi_nr_dl_tti_request_pdu_t*)msg; + + if(!(pull32(ppReadPackedMsg, &value->PDUSize, end) && + pull16(ppReadPackedMsg, &value->PDUType, end) )) + return 0; + + + // first match the pdu type, then call the respective function + switch(value->PDUType) + { + case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: + { + if(!(unpack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppReadPackedMsg,end))) + return 0; + } + break; + + case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: + { + if(!(unpack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppReadPackedMsg,end))) + return 0; + } + break; + case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: + { + if(!(unpack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppReadPackedMsg,end))) + return 0; + } + break; + case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: + { + if(!(unpack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppReadPackedMsg,end))) + return 0; + } + break; + + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType ); + } + break; + } + + return 1; +} + + + + +static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->number_pdcch_ofdm_symbols, end) && + pull8(ppReadPackedMsg, &value->number_dci, end) && + pull16(ppReadPackedMsg, &value->number_pdu, end) && + pull8(ppReadPackedMsg, &value->number_pdsch_rnti, end) && + pull16(ppReadPackedMsg, &value->transmission_power_pcfich, end))) + return 0; + + if(value->number_pdu > NFAPI_DL_CONFIG_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of dl config pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_pdu, NFAPI_DL_CONFIG_MAX_PDU); + return 0; + } + + if(value->number_pdu) + { + value->dl_config_pdu_list = (nfapi_dl_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_dl_config_request_pdu_t) * value->number_pdu, config); + if(value->dl_config_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate dl config pdu list (count:%d)\n", __FUNCTION__, value->number_pdu); + return 0; + } + } + else + { + value->dl_config_pdu_list = 0; + } + + uint16_t i; + uint16_t total_number_of_pdus = value->number_pdu; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_dl_config_request_pdu_t* pdu = &(value->dl_config_pdu_list[i]); + + if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && + pull8(ppReadPackedMsg, &pdu->pdu_size, end))) + return 0; + + uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; + + if(packedPduEnd > end) + { + // pdu end of beyond buffer end + return 0; + } + + switch(pdu->pdu_type) + { + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel8, &unpack_dl_config_dci_dl_pdu_rel8_value}, + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel9, &unpack_dl_config_dci_dl_pdu_rel9_value}, + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel10, &unpack_dl_config_dci_dl_pdu_rel10_value}, + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel11, &unpack_dl_config_dci_dl_pdu_rel11_value}, + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel12, &unpack_dl_config_dci_dl_pdu_rel12_value}, + { NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG, &pdu->dci_dl_pdu.dci_dl_pdu_rel13, &unpack_dl_config_dci_dl_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG, &pdu->bch_pdu.bch_pdu_rel8, &unpack_dl_config_bch_pdu_rel8_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_MCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG, &pdu->mch_pdu.mch_pdu_rel8, &unpack_dl_config_mch_pdu_rel8_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel8, &unpack_dl_config_dlsch_pdu_rel8_value}, + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel9, &unpack_dl_config_dlsch_pdu_rel9_value}, + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel10, &unpack_dl_config_dlsch_pdu_rel10_value}, + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel11, &unpack_dl_config_dlsch_pdu_rel11_value}, + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel12, &unpack_dl_config_dlsch_pdu_rel12_value}, + { NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG, &pdu->dlsch_pdu.dlsch_pdu_rel13, &unpack_dl_config_dlsch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_PCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG, &pdu->pch_pdu.pch_pdu_rel8, &unpack_dl_config_pch_pdu_rel8_value}, + { NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG, &pdu->pch_pdu.pch_pdu_rel13, &unpack_dl_config_pch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_PRS_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG, &pdu->prs_pdu.prs_pdu_rel9, &unpack_dl_config_prs_pdu_rel9_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel10, &unpack_dl_config_csi_rs_pdu_rel10_value}, + { NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG, &pdu->csi_rs_pdu.csi_rs_pdu_rel13, &unpack_dl_config_csi_rs_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel8, &unpack_dl_config_dci_dl_pdu_rel8_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel9, &unpack_dl_config_dci_dl_pdu_rel9_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel10, &unpack_dl_config_dci_dl_pdu_rel10_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel11, &unpack_dl_config_dci_dl_pdu_rel11_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel12, &unpack_dl_config_dci_dl_pdu_rel12_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG, &pdu->epdcch_pdu.epdcch_pdu_rel13, &unpack_dl_config_dci_dl_pdu_rel13_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG, &pdu->epdcch_pdu.epdcch_params_rel11, &unpack_dl_config_epdcch_params_rel11_value}, + { NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG, &pdu->epdcch_pdu.epdcch_params_rel13, &unpack_dl_config_epdcch_params_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG, &pdu->mpdcch_pdu.mpdcch_pdu_rel13, &unpack_dl_config_mpdcch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG, &pdu->nbch_pdu.nbch_pdu_rel13, &unpack_dl_config_nbch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG, &pdu->npdcch_pdu.npdcch_pdu_rel13, &unpack_dl_config_npdcch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + + } + break; + case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG, &pdu->ndlsch_pdu.ndlsch_pdu_rel13, &unpack_dl_config_ndlsch_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + + } + break; + default: + // Need to log an error + break; + } + } + + return 1; +} + + +static uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t*)msg; + + if (!(pull16(ppReadPackedMsg,&pNfapiMsg->SFN, end) && + pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) && + pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end) && + pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end) && + pullarray8(ppReadPackedMsg,pNfapiMsg->dl_tti_request_body.nUe ,256,pNfapiMsg->dl_tti_request_body.nGroup, end) + //pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end) + )) + return 0; + + int arr[12]; + for(int i=0;idl_tti_request_body.nGroup;i++) + { + for(int j=0;jdl_tti_request_body.nUe[i];j++) + { + arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j]; + } + if(!(pullarrays32(ppReadPackedMsg,arr,12,pNfapiMsg->dl_tti_request_body.nUe[i], end))) + return 0; + } + + for(int i=0;idl_tti_request_body.nPDUs;i++) + { + if(!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i])) + return 0; + } + +return 1; +} + + +static uint8_t unpack_ul_tti_request_prach_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_prach_pdu_t* prach_pdu = (nfapi_nr_prach_pdu_t*)tlv; + + return( + pull16(ppReadPackedMsg, &prach_pdu->phys_cell_id, end) && + pull8(ppReadPackedMsg, &prach_pdu->num_prach_ocas, end) && + pull8(ppReadPackedMsg, &prach_pdu->prach_format, end) && + pull8(ppReadPackedMsg, &prach_pdu->num_ra, end) && + pull8(ppReadPackedMsg, &prach_pdu->prach_start_symbol, end) && + pull16(ppReadPackedMsg, &prach_pdu->num_cs, end) + // TODO: ignoring beamforming tlv for now + ); +} + + +static uint8_t unpack_ul_tti_request_pucch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_pucch_pdu_t* pucch_pdu = (nfapi_nr_pucch_pdu_t*)tlv; + + return( + pull16(ppReadPackedMsg, &pucch_pdu->rnti, end) && + pull32(ppReadPackedMsg, &pucch_pdu->handle, end) && + pull16(ppReadPackedMsg, &pucch_pdu->bwp_size, end) && + pull16(ppReadPackedMsg, &pucch_pdu->bwp_start, end) && + pull8(ppReadPackedMsg, &pucch_pdu->subcarrier_spacing, end) && + pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end) && + pull8(ppReadPackedMsg, &pucch_pdu->format_type, end) && + pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end) && + pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end) && + pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end) && + pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end) && + pull8(ppReadPackedMsg, &pucch_pdu->nr_of_symbols, end) && + pull8(ppReadPackedMsg, &pucch_pdu->freq_hop_flag, end) && + pull16(ppReadPackedMsg, &pucch_pdu->second_hop_prb, end) && + pull8(ppReadPackedMsg, &pucch_pdu->group_hop_flag, end) && + pull8(ppReadPackedMsg, &pucch_pdu->sequence_hop_flag, end) && + pull16(ppReadPackedMsg, &pucch_pdu->hopping_id, end) && + pull16(ppReadPackedMsg, &pucch_pdu->initial_cyclic_shift, end) && + pull16(ppReadPackedMsg, &pucch_pdu->data_scrambling_id, end) && + pull8(ppReadPackedMsg, &pucch_pdu->time_domain_occ_idx, end) && + pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_idx, end) && + pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_len, end) && + pull8(ppReadPackedMsg, &pucch_pdu->add_dmrs_flag, end) && + pull16(ppReadPackedMsg, &pucch_pdu->dmrs_scrambling_id, end) && + pull8(ppReadPackedMsg, &pucch_pdu->dmrs_cyclic_shift, end) && + pull8(ppReadPackedMsg, &pucch_pdu->sr_flag, end) && + pull8(ppReadPackedMsg, &pucch_pdu->bit_len_harq, end) && + pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part1, end) && + pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part2, end) + // TODO: ignoring beamforming tlv for now + ); +} + + +static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_pusch_pdu_t* pusch_pdu = (nfapi_nr_pusch_pdu_t*)tlv; + + if (!( + pull16(ppReadPackedMsg, &pusch_pdu->pdu_bit_map, end) && + pull16(ppReadPackedMsg, &pusch_pdu->rnti, end) && + pull32(ppReadPackedMsg, &pusch_pdu->handle, end) && + pull16(ppReadPackedMsg, &pusch_pdu->bwp_size, end) && + pull16(ppReadPackedMsg, &pusch_pdu->bwp_start, end) && + pull8(ppReadPackedMsg, &pusch_pdu->subcarrier_spacing, end) && + pull8(ppReadPackedMsg, &pusch_pdu->cyclic_prefix, end) && + pull16(ppReadPackedMsg, &pusch_pdu->target_code_rate, end) && + pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) && + pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end) && + pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) && + pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end) && + pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && + pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end) && + pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && + pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end) && + pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) && + pull8(ppReadPackedMsg, &pusch_pdu->scid, end) && + pull8(ppReadPackedMsg, &pusch_pdu->num_dmrs_cdm_grps_no_data, end) && + pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) && + pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end) && + pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc,end) && + pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) && + pull16(ppReadPackedMsg, &pusch_pdu->rb_start, end) && + pull16(ppReadPackedMsg, &pusch_pdu->rb_size, end) && + pull8(ppReadPackedMsg, &pusch_pdu->vrb_to_prb_mapping, end) && + pull8(ppReadPackedMsg, &pusch_pdu->frequency_hopping, end) && + pull16(ppReadPackedMsg, &pusch_pdu->tx_direct_current_location, end) && + pull8(ppReadPackedMsg, &pusch_pdu->uplink_frequency_shift_7p5khz, end) && + pull8(ppReadPackedMsg, &pusch_pdu->start_symbol_index, end) && + pull8(ppReadPackedMsg, &pusch_pdu->nr_of_symbols, end) + // TODO: ignoring beamforming tlv for now + )) + return 0; + + + //Pack Optional Data only included if indicated in pduBitmap + switch(pusch_pdu->pdu_bit_map){ + case PUSCH_PDU_BITMAP_PUSCH_DATA: + { + // pack optional TLVs + return( + pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.rv_index, end) && + pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.harq_process_id, end) && + pull32(ppReadPackedMsg, &pusch_pdu->pusch_data.tb_size, end) && + pull16(ppReadPackedMsg, &pusch_pdu->pusch_data.num_cb, end) && + pullarray8(ppReadPackedMsg, pusch_pdu->pusch_data.cb_present_and_position,1,1,end) + ); + } + break; + + case PUSCH_PDU_BITMAP_PUSCH_UCI: + { + return( + pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.harq_ack_bit_length, end) && + pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part1_bit_length, end) && + pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part2_bit_length, end) && + pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.alpha_scaling, end) && + pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_harq_ack, end) && + pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi1, end) && + pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi2, end) + ); + } + break; + + case PUSCH_PDU_BITMAP_PUSCH_PTRS: + { + return( + pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.num_ptrs_ports, end) && + pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, end) && ++ pull16(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, end) && ++ pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, end) && + pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_time_density, end) && + pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_freq_density, end) && + pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ul_ptrs_power, end) + ); + } + break; + + case PUSCH_PDU_BITMAP_DFTS_OFDM: + { + return( + pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_group_number, end) && + pull16(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_sequence_number, end) && + pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, end) && + pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, end) + ); + } + break; + + default: + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map ); + } + } + + return 1; +} + + +static uint8_t unpack_ul_tti_request_srs_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nr_srs_pdu_t* srs_pdu = (nfapi_nr_srs_pdu_t*)tlv; + + return( + pull16(ppReadPackedMsg, &srs_pdu->rnti, end) && + pull32(ppReadPackedMsg, &srs_pdu->handle, end) && + pull16(ppReadPackedMsg, &srs_pdu->bwp_size, end) && + pull16(ppReadPackedMsg, &srs_pdu->bwp_start, end) && + pull8(ppReadPackedMsg, &srs_pdu->subcarrier_spacing, end) && + pull8(ppReadPackedMsg, &srs_pdu->cyclic_prefix, end) && + pull8(ppReadPackedMsg, &srs_pdu->num_ant_ports, end) && + pull8(ppReadPackedMsg, &srs_pdu->num_symbols, end) && + pull8(ppReadPackedMsg, &srs_pdu->num_repetitions, end) && + pull8(ppReadPackedMsg, &srs_pdu->time_start_position, end) && + pull8(ppReadPackedMsg, &srs_pdu->config_index, end) && + pull16(ppReadPackedMsg, &srs_pdu->sequence_id, end) && + pull8(ppReadPackedMsg, &srs_pdu->bandwidth_index, end) && + pull8(ppReadPackedMsg, &srs_pdu->comb_size, end) && + pull8(ppReadPackedMsg, &srs_pdu->comb_offset, end) && + pull8(ppReadPackedMsg, &srs_pdu->cyclic_shift, end) && + pull8(ppReadPackedMsg, &srs_pdu->frequency_position, end) && + pull8(ppReadPackedMsg, &srs_pdu->frequency_shift, end) && + pull8(ppReadPackedMsg, &srs_pdu->frequency_hopping, end) && + pull8(ppReadPackedMsg, &srs_pdu->group_or_sequence_hopping, end) && + pull8(ppReadPackedMsg, &srs_pdu->resource_type, end) && + pull16(ppReadPackedMsg, &srs_pdu->t_srs, end) && + pull16(ppReadPackedMsg, &srs_pdu->t_offset, end) + // TODO: ignoring beamforming tlv for now + ); +} + + +static uint8_t unpack_ul_tti_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) +{ + nfapi_nr_ul_tti_request_number_of_pdus_t* pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_pdus_t*)msg; + + if(!(pull16(ppReadPackedMsg, &pNfapiMsg->pdu_size, end) && + pull16(ppReadPackedMsg, &pNfapiMsg->pdu_type, end) )) + return 0; + + + // first natch the pdu type, then call the respective function + switch(pNfapiMsg->pdu_type) + { + + case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: + { + if(!unpack_ul_tti_request_prach_pdu(&pNfapiMsg->prach_pdu, ppReadPackedMsg, end)) + return 0; + } + break; + + case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: + { + if(!unpack_ul_tti_request_pucch_pdu(&pNfapiMsg->pucch_pdu, ppReadPackedMsg, end)) + return 0; + } + break; + + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + { + if(!unpack_ul_tti_request_pusch_pdu(&pNfapiMsg->pusch_pdu, ppReadPackedMsg, end)) + return 0; + } + break; + + case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: + { + if(!unpack_ul_tti_request_srs_pdu(&pNfapiMsg->srs_pdu, ppReadPackedMsg, end)) + return 0; + } + break; + + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", pNfapiMsg->pdu_type ); + } + break; + + + } + + return 1; +} + + +static uint8_t unpack_ul_tti_groups_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) +{ + nfapi_nr_ul_tti_request_number_of_groups_t* pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_groups_t*)msg; + + if(!pull8(ppReadPackedMsg, &pNfapiMsg->n_ue, end)) + return 0; + for (int i = 0; i < pNfapiMsg->n_ue; i++) + { + if(!pull8(ppReadPackedMsg, &pNfapiMsg->ue_list[i].pdu_idx ,end) ) + return 0; + } + return 1; +} + + +static uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t*)msg; + + if (!( + pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && + pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) && + pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end) && + pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end) && + pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end) && + pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end) && + pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end) )) + return 0; + + for(int i=0; i< pNfapiMsg->n_pdus; i++) + { + if (!unpack_ul_tti_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdus_list[i])) + return 0; + } + + for(int i=0; i< pNfapiMsg->n_group; i++) + { + if (!unpack_ul_tti_groups_list_value(ppReadPackedMsg, end, &pNfapiMsg->groups_list[i])) + return 0; + } + + return 1; +} + + + +static uint8_t unpack_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->dl_config_request_body, &unpack_dl_config_request_body_value}, + }; + + return ( pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_ul_config_ulsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + + + + nfapi_ul_config_ulsch_pdu_rel8_t* ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t*)tlv; + + return (pull32(ppReadPackedMsg, &ulsch_pdu_rel8->handle, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel8->size, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->resource_block_start, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->number_of_resource_blocks, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->modulation_type, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->cyclic_shift_2_for_drms, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->frequency_hopping_enabled_flag, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->frequency_hopping_bits, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->new_data_indication, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->redundancy_version, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->harq_process_number, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->ul_tx_mode, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->current_tx_nb, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel8->n_srs, end )); +} + +static uint8_t unpack_ul_config_ulsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel10_t* ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &ulsch_pdu_rel10->resource_allocation_type, end) && + pull32(ppReadPackedMsg, &ulsch_pdu_rel10->resource_block_coding, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel10->transport_blocks, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel10->transmission_scheme, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel10->number_of_layers, end) & + pull8(ppReadPackedMsg, &ulsch_pdu_rel10->codebook_index, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel10->disable_sequence_hopping_flag, end)); +} +static uint8_t unpack_ul_config_ulsch_pdu_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel11_t* ulsch_pdu_rel11 = (nfapi_ul_config_ulsch_pdu_rel11_t*)tlv; + + return ( pull8(ppReadPackedMsg, &ulsch_pdu_rel11->virtual_cell_id_enabled_flag, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel11->npusch_identity, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel11->dmrs_config_flag, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel11->ndmrs_csh_identity, end)); +} +static uint8_t unpack_ul_config_ulsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_pdu_rel13_t* ulsch_pdu_rel13 = (nfapi_ul_config_ulsch_pdu_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &ulsch_pdu_rel13->ue_type, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel13->total_number_of_repetitions, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel13->repetition_number, end) && + pull16(ppReadPackedMsg, &ulsch_pdu_rel13->initial_transmission_sf_io, end) && + pull8(ppReadPackedMsg, &ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, end)); +} +static uint8_t unpack_ul_config_cqi_ri_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel8_t* cqi_ri_info_rel8 = (nfapi_ul_config_cqi_ri_information_rel8_t*)tlv; + + return (pull8(ppReadPackedMsg, &cqi_ri_info_rel8->dl_cqi_pmi_size_rank_1, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel8->dl_cqi_pmi_size_rank_greater_1, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel8->ri_size, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel8->delta_offset_cqi, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel8->delta_offset_ri, end)); +} + +static uint8_t unpack_ul_config_cqi_ri_info_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel9_t* cqi_ri_info_rel9 = (nfapi_ul_config_cqi_ri_information_rel9_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->report_type, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel9->delta_offset_cqi, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel9->delta_offset_ri, end))) + return 0; + + switch(cqi_ri_info_rel9->report_type) + { + case NFAPI_CSI_REPORT_TYPE_PERIODIC: + { + if(!(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size, end) && + pull8(ppReadPackedMsg, &cqi_ri_info_rel9->periodic_cqi_pmi_ri_report.control_type, end))) + return 0; + } + break; + case NFAPI_CSI_REPORT_TYPE_APERIODIC: + { + if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc, end) ==0) + return 0; + + uint8_t i; + for(i = 0; i < cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.number_of_cc; ++i) + { + if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].ri_size, end) == 0) + return 0; + + uint8_t j; + for(j = 0; j < 8; ++j) + { + if(pull8(ppReadPackedMsg, &cqi_ri_info_rel9->aperiodic_cqi_pmi_ri_report.cc[i].dl_cqi_pmi_size[j], end) == 0) + return 0; + } + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid report type %d \n", cqi_ri_info_rel9->report_type ); + return 0; + } + break; + }; + return 1; +} + +// NOTE : This function is a little unconventional as we uese the side to +// determine the report type +static uint8_t unpack_ul_config_cqi_ri_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_ri_information_rel13_t* cqi_ri_info_rel13 = (nfapi_ul_config_cqi_ri_information_rel13_t*)tlv; + if(cqi_ri_info_rel13->tl.length == 0) + { + cqi_ri_info_rel13->report_type = NFAPI_CSI_REPORT_TYPE_APERIODIC; + } + else + { + cqi_ri_info_rel13->report_type = NFAPI_CSI_REPORT_TYPE_PERIODIC; + if(pull16(ppReadPackedMsg, &cqi_ri_info_rel13->periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2, end) == 0) + return 0; + } + return 1; +} +static uint8_t unpack_ul_config_cqi_init_tx_params_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_initial_transmission_parameters_rel8_t* init_tx_params_rel8 = (nfapi_ul_config_initial_transmission_parameters_rel8_t*)tlv; + + return (pull8(ppReadPackedMsg, &init_tx_params_rel8->n_srs_initial, end) && + pull8(ppReadPackedMsg, &init_tx_params_rel8->initial_number_of_resource_blocks, end)); +} +static uint8_t unpack_ul_config_ulsch_harq_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_harq_information_rel10_t* harq_info_rel10 = (nfapi_ul_config_ulsch_harq_information_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &harq_info_rel10->harq_size, end) && + pull8(ppReadPackedMsg, &harq_info_rel10->delta_offset_harq, end) && + pull8(ppReadPackedMsg, &harq_info_rel10->ack_nack_mode, end)); +} + +static uint8_t unpack_ul_config_ulsch_harq_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ulsch_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_ulsch_harq_information_rel13_t*)tlv; + + return (pull16(ppReadPackedMsg, &harq_info_rel13->harq_size_2, end) && + pull8(ppReadPackedMsg, &harq_info_rel13->delta_offset_harq_2, end)); +} + +static uint8_t unpack_ul_config_ue_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel8_t* ue_info_rel8 = (nfapi_ul_config_ue_information_rel8_t*)tlv; + + return (pull32(ppReadPackedMsg, &ue_info_rel8->handle, end) && + pull16(ppReadPackedMsg, (uint16_t *)&ue_info_rel8->rnti, end)); +} +static uint8_t unpack_ul_config_ue_info_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel11_t* ue_info_rel11 = (nfapi_ul_config_ue_information_rel11_t*)tlv; + + return (pull8(ppReadPackedMsg, &ue_info_rel11->virtual_cell_id_enabled_flag, end) && + pull16(ppReadPackedMsg, &ue_info_rel11->npusch_identity, end)); +} +static uint8_t unpack_ul_config_ue_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_ue_information_rel13_t* ue_info_rel13 = (nfapi_ul_config_ue_information_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &ue_info_rel13->ue_type, end) && + pull8(ppReadPackedMsg, &ue_info_rel13->empty_symbols, end) && + pull16(ppReadPackedMsg, &ue_info_rel13->total_number_of_repetitions, end) && + pull16(ppReadPackedMsg, &ue_info_rel13->repetition_number, end)); +} + +static uint8_t unpack_ul_config_cqi_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel8_t* cqi_info_rel8 = (nfapi_ul_config_cqi_information_rel8_t*)tlv; + + return ( pull16(ppReadPackedMsg, &cqi_info_rel8->pucch_index, end) && + pull8(ppReadPackedMsg, &cqi_info_rel8->dl_cqi_pmi_size, end)); +} +static uint8_t unpack_ul_config_cqi_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel10_t* cqi_info_rel10 = (nfapi_ul_config_cqi_information_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &cqi_info_rel10->number_of_pucch_resource, end) && + pull16(ppReadPackedMsg, &cqi_info_rel10->pucch_index_p1, end)); +} +static uint8_t unpack_ul_config_cqi_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_cqi_information_rel13_t* cqi_info_rel13 = (nfapi_ul_config_cqi_information_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &cqi_info_rel13->csi_mode, end) && + pull16(ppReadPackedMsg, &cqi_info_rel13->dl_cqi_pmi_size_2, end) && + pull8(ppReadPackedMsg, &cqi_info_rel13->starting_prb, end) && + pull8(ppReadPackedMsg, &cqi_info_rel13->n_prb, end) && + pull8(ppReadPackedMsg, &cqi_info_rel13->cdm_index, end) && + pull8(ppReadPackedMsg, &cqi_info_rel13->n_srs, end)); +} + +static uint8_t unpack_ul_config_sr_info_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_sr_information_rel8_t* sr_info_rel8 = (nfapi_ul_config_sr_information_rel8_t*)tlv; + + return ( pull16(ppReadPackedMsg, &sr_info_rel8->pucch_index, end)); +} + +static uint8_t unpack_ul_config_sr_info_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_sr_information_rel10_t* sr_info_rel10 = (nfapi_ul_config_sr_information_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &sr_info_rel10->number_of_pucch_resources, end) && + pull16(ppReadPackedMsg, &sr_info_rel10->pucch_index_p1, end)); +} + +static uint8_t unpack_ul_config_harq_info_rel10_tdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel10_tdd_t* harq_info_tdd_rel10 = (nfapi_ul_config_harq_information_rel10_tdd_t*)tlv; + + return (pull8(ppReadPackedMsg, &harq_info_tdd_rel10->harq_size, end) && + pull8(ppReadPackedMsg, &harq_info_tdd_rel10->ack_nack_mode, end) && + pull8(ppReadPackedMsg, &harq_info_tdd_rel10->number_of_pucch_resources, end) && + pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_0, end) && + pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_1, end) && + pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_2, end) && + pull16(ppReadPackedMsg, &harq_info_tdd_rel10->n_pucch_1_3, end)); +} + +static uint8_t unpack_ul_config_harq_info_rel8_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel8_fdd_t* harq_info_fdd_rel8 = (nfapi_ul_config_harq_information_rel8_fdd_t*)tlv; + + return (pull16(ppReadPackedMsg, &harq_info_fdd_rel8->n_pucch_1_0, end) && + pull8(ppReadPackedMsg, &harq_info_fdd_rel8->harq_size, end)); +} + +static uint8_t unpack_ul_config_harq_info_rel9_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel9_fdd_t* harq_info_fdd_rel9 = (nfapi_ul_config_harq_information_rel9_fdd_t*)tlv; + + return (pull8(ppReadPackedMsg, &harq_info_fdd_rel9->harq_size, end) && + pull8(ppReadPackedMsg, &harq_info_fdd_rel9->ack_nack_mode, end) && + pull8(ppReadPackedMsg, &harq_info_fdd_rel9->number_of_pucch_resources, end) && + pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_0, end) && + pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_1, end) && + pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_2, end) && + pull16(ppReadPackedMsg, &harq_info_fdd_rel9->n_pucch_1_3, end)); +} + +static uint8_t unpack_ul_config_harq_info_rel11_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel11_t* harq_info_rel11 = (nfapi_ul_config_harq_information_rel11_t*)tlv; + + return (pull8(ppReadPackedMsg, &harq_info_rel11->num_ant_ports, end) && + pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_0, end) && + pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_1, end) && + pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_2, end) && + pull16(ppReadPackedMsg, &harq_info_rel11->n_pucch_2_3, end)); +} + +static uint8_t unpack_ul_config_harq_info_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_harq_information_rel13_t* harq_info_rel13 = (nfapi_ul_config_harq_information_rel13_t*)tlv; + + return (pull16(ppReadPackedMsg, &harq_info_rel13->harq_size_2, end) && + pull8(ppReadPackedMsg, &harq_info_rel13->starting_prb, end) && + pull8(ppReadPackedMsg, &harq_info_rel13->n_prb, end) && + pull8(ppReadPackedMsg, &harq_info_rel13->cdm_index, end) && + pull8(ppReadPackedMsg, &harq_info_rel13->n_srs, end)); +} + + +static uint8_t unpack_ul_config_srs_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel8_t* srs_pdu_rel8 = (nfapi_ul_config_srs_pdu_rel8_t*)tlv; + + return (pull32(ppReadPackedMsg, &srs_pdu_rel8->handle, end) && + pull16(ppReadPackedMsg, &srs_pdu_rel8->size, end) && + pull16(ppReadPackedMsg, &srs_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &srs_pdu_rel8->srs_bandwidth, end) && + pull8(ppReadPackedMsg, &srs_pdu_rel8->frequency_domain_position, end) && + pull8(ppReadPackedMsg, &srs_pdu_rel8->srs_hopping_bandwidth, end) && + pull8(ppReadPackedMsg, &srs_pdu_rel8->transmission_comb, end) && + pull16(ppReadPackedMsg, &srs_pdu_rel8->i_srs, end) && + pull8(ppReadPackedMsg, &srs_pdu_rel8->sounding_reference_cyclic_shift, end)); +} + +static uint8_t unpack_ul_config_srs_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel10_t* srs_pdu_rel10 = (nfapi_ul_config_srs_pdu_rel10_t*)tlv; + return pull8(ppReadPackedMsg, &srs_pdu_rel10->antenna_port, end); +} + +static uint8_t unpack_ul_config_srs_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_srs_pdu_rel13_t* srs_pdu_rel13 = (nfapi_ul_config_srs_pdu_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &srs_pdu_rel13->number_of_combs, end)); +} + +static uint8_t unpack_ul_nb_harq_info_rel13_fdd_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_nb_harq_information_rel13_fdd_t* nb_harq_info_fdd_rel13 = (nfapi_ul_config_nb_harq_information_rel13_fdd_t*)tlv; + + return (pull8(ppReadPackedMsg, &nb_harq_info_fdd_rel13->harq_ack_resource, end)); +} + +static uint8_t unpack_ul_config_nulsch_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_nulsch_pdu_rel13_t* nulsch_pdu_rel13 = (nfapi_ul_config_nulsch_pdu_rel13_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &nulsch_pdu_rel13->nulsch_format, end) && + pull32(ppReadPackedMsg, &nulsch_pdu_rel13->handle, end) && + pull16(ppReadPackedMsg, &nulsch_pdu_rel13->size, end) && + pull16(ppReadPackedMsg, &nulsch_pdu_rel13->rnti, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->subcarrier_indication, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->resource_assignment, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->mcs, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->redudancy_version, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->repetition_number, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->new_data_indication, end) && + pull8(ppReadPackedMsg, &nulsch_pdu_rel13->n_srs, end) && + pull16(ppReadPackedMsg, &nulsch_pdu_rel13->scrambling_sequence_initialization_cinit, end) && + pull16(ppReadPackedMsg, &nulsch_pdu_rel13->sf_idx, end))) + return 0; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel8, &unpack_ul_config_ue_info_rel8_value}, + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel11, &unpack_ul_config_ue_info_rel11_value}, + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &nulsch_pdu_rel13->ue_information.ue_information_rel13, &unpack_ul_config_ue_info_rel13_value}, + { NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG, &nulsch_pdu_rel13->nb_harq_information.nb_harq_information_rel13_fdd, &unpack_ul_nb_harq_info_rel13_fdd_value}, + }; + + return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, 0, 0); +} + +static uint8_t unpack_ul_config_nrach_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_config_nrach_pdu_rel13_t* nrach_pdu_rel13 = (nfapi_ul_config_nrach_pdu_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_0, end) && + pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_1, end) && + pull8(ppReadPackedMsg, &nrach_pdu_rel13->nprach_config_2, end)); +} + + +static uint8_t unpack_ul_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + #define UL_CONFIG_ULSCH_PDU_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &_pdu.ulsch_pdu_rel8, &unpack_ul_config_ulsch_pdu_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &_pdu.ulsch_pdu_rel10, &unpack_ul_config_ulsch_pdu_rel10_value}, \ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG, &_pdu.ulsch_pdu_rel11, &unpack_ul_config_ulsch_pdu_rel11_value}, \ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG, &_pdu.ulsch_pdu_rel13, &unpack_ul_config_ulsch_pdu_rel13_value}, + + #define UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG, &_pdu.cqi_ri_information_rel8, &unpack_ul_config_cqi_ri_info_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG, &_pdu.cqi_ri_information_rel9, &unpack_ul_config_cqi_ri_info_rel9_value}, \ + { NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG, &_pdu.cqi_ri_information_rel13, &unpack_ul_config_cqi_ri_info_rel13_value}, + + #define UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG, &_pdu.harq_information_rel10, &unpack_ul_config_ulsch_harq_info_rel10_value},\ + { NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG, &_pdu.harq_information_rel13, &unpack_ul_config_ulsch_harq_info_rel13_value}, + + #define UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG, &_pdu.initial_transmission_parameters_rel8, &unpack_ul_config_cqi_init_tx_params_rel8_value}, + + #define UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG, &_pdu.ue_information_rel8, &unpack_ul_config_ue_info_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG, &_pdu.ue_information_rel11, &unpack_ul_config_ue_info_rel11_value}, \ + { NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG, &_pdu.ue_information_rel13, &unpack_ul_config_ue_info_rel13_value}, + + #define UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG, &_pdu.cqi_information_rel8, &unpack_ul_config_cqi_info_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG, &_pdu.cqi_information_rel10, &unpack_ul_config_cqi_info_rel10_value}, \ + { NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG, &_pdu.cqi_information_rel13, &unpack_ul_config_cqi_info_rel13_value}, + + #define UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG, &_pdu.sr_information_rel8, &unpack_ul_config_sr_info_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG, &_pdu.sr_information_rel10, &unpack_ul_config_sr_info_rel10_value}, + + #define UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG, &_pdu.harq_information_rel10_tdd, &unpack_ul_config_harq_info_rel10_tdd_value}, \ + { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG, &_pdu.harq_information_rel8_fdd, &unpack_ul_config_harq_info_rel8_fdd_value}, \ + { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG, &_pdu.harq_information_rel9_fdd, &unpack_ul_config_harq_info_rel9_fdd_value}, \ + { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG, &_pdu.harq_information_rel11, &unpack_ul_config_harq_info_rel11_value}, \ + { NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG, &_pdu.harq_information_rel13, &unpack_ul_config_harq_info_rel13_value}, + + #define UL_CONFIG_SRS_PDU_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG, &_pdu.srs_pdu_rel8, &unpack_ul_config_srs_pdu_rel8_value}, \ + { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG, &_pdu.srs_pdu_rel10, &unpack_ul_config_srs_pdu_rel10_value}, \ + { NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG, &_pdu.srs_pdu_rel13, &unpack_ul_config_srs_pdu_rel13_value}, + + #define UL_CONFIG_NULSCH_PDU_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG, &_pdu.nulsch_pdu_rel13, &unpack_ul_config_nulsch_pdu_rel13_value}, + + #define UL_CONFIG_NRACH_PDU_UNPACK_FNS(_pdu) \ + { NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG, &_pdu.nrach_pdu_rel13, &unpack_ul_config_nrach_pdu_rel13_value}, + + + nfapi_ul_config_request_body_t* value = (nfapi_ul_config_request_body_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->number_of_pdus, end) && + pull8(ppReadPackedMsg, &value->rach_prach_frequency_resources, end) && + pull8(ppReadPackedMsg, &value->srs_present, end))) + return 0; + + if(value->number_of_pdus > NFAPI_UL_CONFIG_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of ul config pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_UL_CONFIG_MAX_PDU); + return 0; + } + + if(value->number_of_pdus > 0) + { + value->ul_config_pdu_list = (nfapi_ul_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_ul_config_request_pdu_t) * value->number_of_pdus, config); + + if(value->ul_config_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate ul config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); + return 0; + } + } + else + { + value->ul_config_pdu_list = 0; + } + + + uint16_t i; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_ul_config_request_pdu_t* pdu = &(value->ul_config_pdu_list[i]); + + if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && + pull8(ppReadPackedMsg, &pdu->pdu_size, end))) + return 0; + + uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; + + if(packedPduEnd > end) + { + // pdu end is past buffer end + return 0; + } + + switch(pdu->pdu_type) + { + case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_pdu) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + + case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.ulsch_pdu) + UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.cqi_ri_information) + UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_cqi_ri_pdu.initial_transmission_parameters) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_harq_pdu.ulsch_pdu) + UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(pdu->ulsch_harq_pdu.harq_information) + UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_harq_pdu.initial_transmission_parameters) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu) + UL_CONFIG_CQI_RI_INFO_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information) + UL_CONFIG_ULSCH_HARQ_INFO_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.harq_information) + UL_CONFIG_INIT_TX_PARAMS_UNPACK_FNS(pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_pdu.ue_information) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_pdu.cqi_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_sr_pdu.ue_information) + UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_sr_pdu.sr_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_harq_pdu.ue_information) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.ue_information) + UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.sr_information) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_sr_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.ue_information) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.cqi_information) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_cqi_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.ue_information) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.cqi_information) + UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_cqi_sr_pdu.sr_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.ue_information) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.cqi_information) + UL_CONFIG_UCI_SR_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.sr_information) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->uci_cqi_sr_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_SRS_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_SRS_PDU_UNPACK_FNS(pdu->srs_pdu) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_UCI_UE_INFO_UNPACK_FNS(pdu->harq_buffer_pdu.ue_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_uci_csi_pdu.ulsch_pdu) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->ulsch_uci_csi_pdu.csi_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_uci_harq_pdu.ulsch_pdu) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->ulsch_uci_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_ULSCH_PDU_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu) + UL_CONFIG_UCI_CQI_INFO_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.csi_information) + UL_CONFIG_UCI_HARQ_INFO_UNPACK_FNS(pdu->ulsch_csi_uci_harq_pdu.harq_information) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_NULSCH_PDU_UNPACK_FNS(pdu->nulsch_pdu) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + UL_CONFIG_NRACH_PDU_UNPACK_FNS(pdu->nrach_pdu) + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + } + } + return 1; +} + + +static uint8_t unpack_ul_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_UL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->ul_config_request_body, &unpack_ul_config_request_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_hi_dci0_hi_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_hi_pdu_rel8_t* hi_pdu_rel8 = (nfapi_hi_dci0_hi_pdu_rel8_t*)tlv; + + return( pull8(ppReadPackedMsg, &hi_pdu_rel8->resource_block_start, end) && + pull8(ppReadPackedMsg, &hi_pdu_rel8->cyclic_shift_2_for_drms, end) && + pull8(ppReadPackedMsg, &hi_pdu_rel8->hi_value, end) && + pull8(ppReadPackedMsg, &hi_pdu_rel8->i_phich, end) && + pull16(ppReadPackedMsg, &hi_pdu_rel8->transmission_power, end)); +} + +static uint8_t unpack_hi_dci0_hi_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_hi_pdu_rel10_t* hi_pdu_rel10 = (nfapi_hi_dci0_hi_pdu_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &hi_pdu_rel10->flag_tb2, end) && + pull8(ppReadPackedMsg, &hi_pdu_rel10->hi_value_2, end)); +} + +static uint8_t unpack_hi_dci0_dci_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel8_t* dci_pdu_rel8 = (nfapi_hi_dci0_dci_pdu_rel8_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_pdu_rel8->dci_format, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->cce_index, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->aggregation_level, end) && + pull16(ppReadPackedMsg, &dci_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->resource_block_start, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->number_of_resource_block, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->mcs_1, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->cyclic_shift_2_for_drms, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->frequency_hopping_enabled_flag, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->frequency_hopping_bits, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->new_data_indication_1, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->ue_tx_antenna_seleciton, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->tpc, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->cqi_csi_request, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->ul_index, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel8->dl_assignment_index, end) && + pull32(ppReadPackedMsg, &dci_pdu_rel8->tpc_bitmap, end) && + pull16(ppReadPackedMsg, &dci_pdu_rel8->transmission_power, end)); +} + +static uint8_t unpack_hi_dci0_dci_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel10_t* dci_pdu_rel10 = (nfapi_hi_dci0_dci_pdu_rel10_t*)tlv; + + return (pull8(ppReadPackedMsg, &dci_pdu_rel10->cross_carrier_scheduling_flag, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->carrier_indicator, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->size_of_cqi_csi_feild, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->srs_flag, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->srs_request, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->resource_allocation_flag, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->resource_allocation_type, end) && + pull32(ppReadPackedMsg, &dci_pdu_rel10->resource_block_coding, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->mcs_2, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->new_data_indication_2, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->number_of_antenna_ports, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->tpmi, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->total_dci_length_including_padding, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel10->n_ul_rb, end)); +} + +static uint8_t unpack_hi_dci0_dci_pdu_rel12_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_dci_pdu_rel12_t* dci_pdu_rel12 = (nfapi_hi_dci0_dci_pdu_rel12_t*)tlv; + + return ( pull8(ppReadPackedMsg, &dci_pdu_rel12->pscch_resource, end) && + pull8(ppReadPackedMsg, &dci_pdu_rel12->time_resource_pattern, end)); +} + +static uint8_t unpack_hi_dci0_mpdcch_dci_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t* value = (nfapi_hi_dci0_mpdcch_dci_pdu_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->mpdcch_narrowband, end) && + pull8(ppReadPackedMsg, &value->number_of_prb_pairs, end) && + pull8(ppReadPackedMsg, &value->resource_block_assignment, end) && + pull8(ppReadPackedMsg, &value->mpdcch_transmission_type, end) && + pull8(ppReadPackedMsg, &value->start_symbol, end) && + pull8(ppReadPackedMsg, &value->ecce_index, end) && + pull8(ppReadPackedMsg, &value->aggreagation_level, end) && + pull8(ppReadPackedMsg, &value->rnti_type, end) && + pull16(ppReadPackedMsg, &value->rnti, end) && + pull8(ppReadPackedMsg, &value->ce_mode, end) && + pull16(ppReadPackedMsg, &value->drms_scrambling_init, end) && + pull16(ppReadPackedMsg, &value->initial_transmission_sf_io, end) && + pull16(ppReadPackedMsg, &value->transmission_power, end) && + pull8(ppReadPackedMsg, &value->dci_format, end) && + pull8(ppReadPackedMsg, &value->resource_block_start, end) && + pull8(ppReadPackedMsg, &value->number_of_resource_blocks, end) && + pull8(ppReadPackedMsg, &value->mcs, end) && + pull8(ppReadPackedMsg, &value->pusch_repetition_levels, end) && + pull8(ppReadPackedMsg, &value->frequency_hopping_flag, end) && + pull8(ppReadPackedMsg, &value->new_data_indication, end) && + pull8(ppReadPackedMsg, &value->harq_process, end) && + pull8(ppReadPackedMsg, &value->redudency_version, end) && + pull8(ppReadPackedMsg, &value->tpc, end) && + pull8(ppReadPackedMsg, &value->csi_request, end) && + pull8(ppReadPackedMsg, &value->ul_inex, end) && + pull8(ppReadPackedMsg, &value->dai_presence_flag, end) && + pull8(ppReadPackedMsg, &value->dl_assignment_index, end) && + pull8(ppReadPackedMsg, &value->srs_request, end) && + pull8(ppReadPackedMsg, &value->dci_subframe_repetition_number, end) && + pull32(ppReadPackedMsg, &value->tcp_bitmap, end) && + pull8(ppReadPackedMsg, &value->total_dci_length_include_padding, end) && + pull8(ppReadPackedMsg, &value->number_of_tx_antenna_ports, end) && + pullarray16(ppReadPackedMsg, value->precoding_value, NFAPI_MAX_TX_PHYSICAL_ANTENNA_PORTS, value->number_of_tx_antenna_ports, end)); +} + +static uint8_t unpack_hi_dci0_npdcch_dci_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_hi_dci0_npdcch_dci_pdu_rel13_t* value = (nfapi_hi_dci0_npdcch_dci_pdu_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->ncce_index, end) && + pull8(ppReadPackedMsg, &value->aggregation_level, end) && + pull8(ppReadPackedMsg, &value->start_symbol, end) && + pull16(ppReadPackedMsg, &value->rnti, end) && + pull8(ppReadPackedMsg, &value->scrambling_reinitialization_batch_index, end) && + pull8(ppReadPackedMsg, &value->nrs_antenna_ports_assumed_by_the_ue, end) && + pull8(ppReadPackedMsg, &value->subcarrier_indication, end) && + pull8(ppReadPackedMsg, &value->resource_assignment, end) && + pull8(ppReadPackedMsg, &value->scheduling_delay, end) && + pull8(ppReadPackedMsg, &value->mcs, end) && + pull8(ppReadPackedMsg, &value->redudancy_version, end) && + pull8(ppReadPackedMsg, &value->repetition_number, end) && + pull8(ppReadPackedMsg, &value->new_data_indicator, end) && + pull8(ppReadPackedMsg, &value->dci_subframe_repetition_number, end)); +} + +static uint8_t unpack_hi_dci0_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_hi_dci0_request_body_t* value = (nfapi_hi_dci0_request_body_t*)tlv; + + if(!(pull16(ppReadPackedMsg, &value->sfnsf, end) && + pull8(ppReadPackedMsg, &value->number_of_dci, end) && + pull8(ppReadPackedMsg, &value->number_of_hi, end))) + return 0; + + uint8_t totalNumPdus = value->number_of_hi + value->number_of_dci; + + if(totalNumPdus > NFAPI_HI_DCI0_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of dci0 pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, totalNumPdus, NFAPI_HI_DCI0_MAX_PDU); + return 0; + } + + if(totalNumPdus > 0) + { + value->hi_dci0_pdu_list = (nfapi_hi_dci0_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_hi_dci0_request_pdu_t) * totalNumPdus, config); + if(value->hi_dci0_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate hi dci0 pdu list (count:%d)\n", __FUNCTION__, totalNumPdus); + return 0; + } + } + else + { + value->hi_dci0_pdu_list = 0; + } + + uint8_t i; + for(i = 0; i < totalNumPdus; ++i) + { + nfapi_hi_dci0_request_pdu_t* pdu = &(value->hi_dci0_pdu_list[i]); + + if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && + pull8(ppReadPackedMsg, &pdu->pdu_size, end))) + return 0; + + uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; + + if(packedPduEnd > end) + { + // pdu end if past buffer end + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pdu size to big %d %d\n", __FUNCTION__, packedPduEnd, end); + return 0; + } + + switch(pdu->pdu_type) + { + case NFAPI_HI_DCI0_HI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG, &pdu->hi_pdu.hi_pdu_rel8, &unpack_hi_dci0_hi_pdu_rel8_value}, + { NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG, &pdu->hi_pdu.hi_pdu_rel10, &unpack_hi_dci0_hi_pdu_rel10_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_HI_DCI0_DCI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG, &pdu->dci_pdu.dci_pdu_rel8, &unpack_hi_dci0_dci_pdu_rel8_value}, + { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG, &pdu->dci_pdu.dci_pdu_rel10, &unpack_hi_dci0_dci_pdu_rel10_value}, + { NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG, &pdu->dci_pdu.dci_pdu_rel12, &unpack_hi_dci0_dci_pdu_rel12_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel8, &unpack_hi_dci0_dci_pdu_rel8_value}, + { NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG, &pdu->epdcch_dci_pdu.epdcch_dci_pdu_rel10, &unpack_hi_dci0_dci_pdu_rel10_value}, + { NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG, &pdu->epdcch_dci_pdu.epdcch_parameters_rel11, &unpack_dl_config_epdcch_params_rel11_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG, &pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13, &unpack_hi_dci0_mpdcch_dci_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG, &pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13, &unpack_hi_dci0_npdcch_dci_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid pdu type %d \n", pdu->pdu_type ); + } + break; + }; + } + + return 1; +} +//unpack_ul_dci_pdu_list_value + +static uint8_t unpack_ul_dci_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) +{ + nfapi_nr_ul_dci_request_pdus_t* value = (nfapi_nr_ul_dci_request_pdus_t*)msg; + + for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) + { + if(!pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, end) && + pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, end) && + + pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, end) && + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, end) && + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, end) && + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, end) && + + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, end) && + pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end) && + + pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end)); + + return 0; + } + + return (pull16(ppReadPackedMsg, &value->PDUType, end) && + pull16(ppReadPackedMsg, &value->PDUSize, end) && + pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, end) && + pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, end) && + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, end) && + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, end) && + + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, end) && + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, end) && + pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, end) && + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, end) && + + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, end) && + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, end) && + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, end) && + pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, end) && + + pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, end) && + pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end)); + +} + +static uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ +nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t*)msg; + + if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && + pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) && + pull8(ppReadPackedMsg, &pNfapiMsg->numPdus, end) + )) + return 0; + for(int i=0; i< pNfapiMsg->numPdus; i++) + { + if (!unpack_ul_dci_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->ul_dci_pdu_list[i])) + return 0; + } + + return 1; + +} + +static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_HI_DCI0_REQUEST_BODY_TAG, &pNfapiMsg->hi_dci0_request_body, &unpack_hi_dci0_request_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); + +} +static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) +{ + nfapi_nr_pdu_t* pNfapiMsg = (nfapi_nr_pdu_t*)msg; + + if(!(pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end) && + pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end) && + pull16(ppReadPackedMsg, &pNfapiMsg->PDU_length, end) + )) + return 0; + + uint16_t i = 0; + uint16_t total_number_of_tlvs = pNfapiMsg->num_TLV; + for(; i < total_number_of_tlvs; ++i) + { + + if (!(pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].length, end) && + pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].tag, end))) + return 0; + + switch(pNfapiMsg->TLVs[i].tag){ + case 0: + { + if(!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.direct, 16384, pNfapiMsg->TLVs[i].length, end)) + return 0; + break; + + } + + case 1: + { + if(!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.ptr, pNfapiMsg->TLVs[i].length , pNfapiMsg->TLVs[i].length, end)) + return 0; + break; + + } + + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", pNfapiMsg->TLVs[i].tag ); + break; + } + + } + } + + + return 1; +} + +static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t*)msg; + + if(!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && + pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) && + pull16(ppReadPackedMsg, &pNfapiMsg->Number_of_PDUs, end))) + return 0; + + for(int i=0; i< pNfapiMsg->Number_of_PDUs; i++) + { + if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) + return 0; + } + + return 1; +} + +static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + uint8_t proceed = 1; + nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t*)msg; + + if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0) + return 0; + + while (((uint8_t*)(*ppReadPackedMsg) < end) && proceed) + { + nfapi_tl_t generic_tl; + if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + switch(generic_tl.tag) + { + case NFAPI_TX_REQUEST_BODY_TAG: + { + pNfapiMsg->tx_request_body.tl = generic_tl; + + if( pull16(ppReadPackedMsg, &pNfapiMsg->tx_request_body.number_of_pdus, end) == 0) + return 0; + + if(pNfapiMsg->tx_request_body.number_of_pdus > NFAPI_TX_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of tx pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->tx_request_body.number_of_pdus, NFAPI_TX_MAX_PDU); + return 0; + } + + if(pNfapiMsg->tx_request_body.number_of_pdus > 0) + { + pNfapiMsg->tx_request_body.tx_pdu_list = (nfapi_tx_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_tx_request_pdu_t) * pNfapiMsg->tx_request_body.number_of_pdus, config); + if(pNfapiMsg->tx_request_body.tx_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate tx pdu list (count:%d)\n", __FUNCTION__, pNfapiMsg->tx_request_body.number_of_pdus); + return 0; + } + } + else + { + pNfapiMsg->tx_request_body.tx_pdu_list = 0; + } + + + uint16_t i; + uint16_t totalNumPdus = pNfapiMsg->tx_request_body.number_of_pdus; + for(i = 0; i < totalNumPdus; ++i) + { + nfapi_tx_request_pdu_t* pdu = &(pNfapiMsg->tx_request_body.tx_pdu_list[i]); if (pdu) { uint16_t length = 0; uint16_t index = 0; - + if(!(pull16(ppReadPackedMsg, &length, end) && - pull16(ppReadPackedMsg, &index, end))) + pull16(ppReadPackedMsg, &index, end))) return 0; - + pdu->pdu_length = length; pdu->pdu_index = index; - - - // TODO : May need to rethink this bit + + + // TODO : May need to rethink this bit pdu->num_segments = 1; pdu->segments[0].segment_length = pdu->pdu_length; pdu->segments[0].segment_data = nfapi_p7_allocate(pdu->pdu_length, config); - + if(pdu->segments[0].segment_data) { if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end)) - return 0; + return 0; if (pdu->segments[0].segment_length == 3) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, - pdu->segments[0].segment_data[0], - pdu->segments[0].segment_data[1], - pdu->segments[0].segment_data[2] - ); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, + pdu->segments[0].segment_data[0], + pdu->segments[0].segment_data[1], + pdu->segments[0].segment_data[2] + ); } } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request: Failed to allocate pdu (len:%d) %d/%d %d\n", pdu->pdu_length, totalNumPdus, i, pdu->pdu_index); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request: Failed to allocate pdu (len:%d) %d/%d %d\n", pdu->pdu_length, totalNumPdus, i, pdu->pdu_index); } } else { NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n"); } - } - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request FIXME : Invalid pdu type %d \n", generic_tl.tag ); - } - break; - }; - } - - return 1; -} + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request FIXME : Invalid pdu type %d \n", generic_tl.tag ); + } + break; + }; + } + + return 1; +} static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) { @@ -4578,1253 +6118,1253 @@ static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end return 1; } -static uint8_t unpack_harq_indication_tdd_harq_data_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_harq_indication_tdd_harq_data_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_bundling_t*)tlv; - - return (pull8(ppReadPackedMsg, &value->value_0, end) && - pull8(ppReadPackedMsg, &value->value_1, end)); -} - -static uint8_t unpack_harq_indication_tdd_harq_data_multiplexing(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_harq_indication_tdd_harq_data_multiplexing_t* value = (nfapi_harq_indication_tdd_harq_data_multiplexing_t*)tlv; - - return (pull8(ppReadPackedMsg, &value->value_0, end) && - pull8(ppReadPackedMsg, &value->value_1, end) && - pull8(ppReadPackedMsg, &value->value_2, end) && - pull8(ppReadPackedMsg, &value->value_3, end)); -} -static uint8_t unpack_harq_indication_tdd_harq_data_special_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_harq_indication_tdd_harq_data_special_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_special_bundling_t*)tlv; - return ( pull8(ppReadPackedMsg, &value->value_0, end)); -} -static uint8_t unpack_harq_indication_tdd_harq_data(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_harq_indication_tdd_harq_data_t* value = (nfapi_harq_indication_tdd_harq_data_t*)tlv; - return (pull8(ppReadPackedMsg, &value->value_0, end)); -} - -static uint8_t unpack_harq_indication_tdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_harq_indication_tdd_rel8_t* value = (nfapi_harq_indication_tdd_rel8_t*)tlv; - - if(!(pull8(ppReadPackedMsg, &value->mode, end) && - pull8(ppReadPackedMsg, &value->number_of_ack_nack, end))) - return 0; - - uint8_t result = 0; - switch(value->mode) - { - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: - result = unpack_harq_indication_tdd_harq_data_bundling(&value->harq_data.bundling, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: - result = unpack_harq_indication_tdd_harq_data_multiplexing(&value->harq_data.multiplex, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: - result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data.special_bundling, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: - result = 1; - break; - default: - // TODO add error message - return 0; - break; - } - return result; -} - -static uint8_t unpack_harq_indication_tdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_harq_indication_tdd_rel9_t* value = (nfapi_harq_indication_tdd_rel9_t*)tlv; - - if(!(pull8(ppReadPackedMsg, &value->mode, end) && - pull8(ppReadPackedMsg, &value->number_of_ack_nack, end))) - return 0; - - if(value->number_of_ack_nack > NFAPI_MAX_NUMBER_ACK_NACK_TDD) - { - // TODO : add error message - return 0; - } - - uint16_t idx = 0; - for(idx = 0; idx < value->number_of_ack_nack; ++idx) - { - uint8_t result = 0; - switch(value->mode) - { - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: - result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].bundling, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: - result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].multiplex, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: - result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data[idx].special_bundling, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: - result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].channel_selection, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: - result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_3, ppReadPackedMsg, end); - break; - default: - // TODO add error message - return 0; - break; - } - - if(result == 0) - return 0; - } - return 1; -} - -static uint8_t unpack_harq_indication_tdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_harq_indication_tdd_rel13_t* value = (nfapi_harq_indication_tdd_rel13_t*)tlv; - - if(!(pull8(ppReadPackedMsg, &value->mode, end) && - pull16(ppReadPackedMsg, &value->number_of_ack_nack, end))) - return 0; - - if(value->number_of_ack_nack > NFAPI_MAX_NUMBER_ACK_NACK_TDD) - { - // TODO : add error message - return 0; - } - - uint16_t idx = 0; - for(idx = 0; idx < value->number_of_ack_nack; ++idx) - { - uint8_t result = 0; - switch(value->mode) - { - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: - result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].bundling, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: - result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].multiplex, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: - result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data[idx].special_bundling, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: - result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].channel_selection, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: - result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_3, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_4: - result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_4, ppReadPackedMsg, end); - break; - case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_5: - result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_5, ppReadPackedMsg, end); - break; - default: - // TODO add error message - return 0; - break; - } - - if(result == 0) - return 0; - } - return 1; -} - -static uint8_t unpack_harq_indication_fdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_harq_indication_fdd_rel8_t* value = (nfapi_harq_indication_fdd_rel8_t*)tlv; - return (pull8(ppReadPackedMsg, &value->harq_tb1, end) && - pull8(ppReadPackedMsg, &value->harq_tb2, end)); -} - -static uint8_t unpack_harq_indication_fdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_harq_indication_fdd_rel9_t* value = (nfapi_harq_indication_fdd_rel9_t*)tlv; - - return (pull8(ppReadPackedMsg, &value->mode, end) && - pull8(ppReadPackedMsg, &value->number_of_ack_nack, end) && - pullarray8(ppReadPackedMsg, value->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL9_MAX, value->number_of_ack_nack, end)); -} - -static uint8_t unpack_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_harq_indication_fdd_rel13_t* value = (nfapi_harq_indication_fdd_rel13_t*)tlv; - - return (pull8(ppReadPackedMsg, &value->mode, end) && - pull16(ppReadPackedMsg, &value->number_of_ack_nack, end) && - pullarray8(ppReadPackedMsg, value->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL13_MAX, value->number_of_ack_nack, end)); -} - -static uint8_t unpack_ul_cqi_information_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_ul_cqi_information_t* value = (nfapi_ul_cqi_information_t*)tlv; - - return (pull8(ppReadPackedMsg, &value->ul_cqi, end) && - pull8(ppReadPackedMsg, &value->channel, end)); -} - - - -static uint8_t unpack_harq_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_harq_indication_body_t* value = (nfapi_harq_indication_body_t*)tlv; - uint8_t* harqBodyEnd = *ppReadPackedMsg + value->tl.length; - - if(harqBodyEnd > end) - return 0; - - if(pull16(ppReadPackedMsg, &value->number_of_harqs, end) == 0) - return 0; - - if(value->number_of_harqs > NFAPI_HARQ_IND_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of harq ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_harqs, NFAPI_HARQ_IND_MAX_PDU); - return 0; - } - - value->harq_pdu_list = (nfapi_harq_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_harq_indication_pdu_t) * value->number_of_harqs, config); - if(value->harq_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_harqs); - return 0; - } - - uint8_t i = 0; - for(i = 0; i < value->number_of_harqs; ++i) - { - nfapi_harq_indication_pdu_t* pdu = &(value->harq_pdu_list[i]); - if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) - return 0; - - uint8_t* harqPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; - - unpack_tlv_t unpack_fns[] = - { - { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, - { NFAPI_HARQ_INDICATION_TDD_REL8_TAG, &pdu->harq_indication_tdd_rel8, &unpack_harq_indication_tdd_rel8_value}, - { NFAPI_HARQ_INDICATION_TDD_REL9_TAG, &pdu->harq_indication_tdd_rel9, &unpack_harq_indication_tdd_rel9_value}, - { NFAPI_HARQ_INDICATION_TDD_REL13_TAG, &pdu->harq_indication_tdd_rel13, &unpack_harq_indication_tdd_rel13_value}, - { NFAPI_HARQ_INDICATION_FDD_REL8_TAG, &pdu->harq_indication_fdd_rel8, &unpack_harq_indication_fdd_rel8_value}, - { NFAPI_HARQ_INDICATION_FDD_REL9_TAG, &pdu->harq_indication_fdd_rel9, &unpack_harq_indication_fdd_rel9_value}, - { NFAPI_HARQ_INDICATION_FDD_REL13_TAG, &pdu->harq_indication_fdd_rel13, &unpack_harq_indication_fdd_rel13_value}, - { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, &unpack_ul_cqi_information_value} - }; - - if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, harqPduInstanceEnd, 0, 0) == 0) - return 0; - - } - - return 1; -} - -static uint8_t unpack_harq_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_harq_indication_t *pNfapiMsg = (nfapi_harq_indication_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->harq_indication_body, &unpack_harq_indication_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_crc_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_crc_indication_rel8_t* crc_pdu_rel8 = (nfapi_crc_indication_rel8_t*)tlv; - return ( pull8(ppReadPackedMsg, &crc_pdu_rel8->crc_flag, end) ); -} - -static uint8_t unpack_crc_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_crc_indication_body_t* value = (nfapi_crc_indication_body_t*)tlv; - uint8_t* crcBodyEnd = *ppReadPackedMsg + value->tl.length; - - if(crcBodyEnd > end) - return 0; - - if(pull16(ppReadPackedMsg, &value->number_of_crcs, end) == 0) - return 0; - - if(value->number_of_crcs > NFAPI_CRC_IND_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of crc ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_crcs, NFAPI_CRC_IND_MAX_PDU); - return 0; - } - - if(value->number_of_crcs > 0) - { - value->crc_pdu_list = (nfapi_crc_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_crc_indication_pdu_t) * value->number_of_crcs, config); - if(value->crc_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate crc ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_crcs); - return 0; - } - } - else - { - value->crc_pdu_list = 0; - } - - - uint8_t i = 0; - for(i = 0; i < value->number_of_crcs; ++i) - { - nfapi_crc_indication_pdu_t* pdu = &(value->crc_pdu_list[i]); - - if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) - return 0; - - uint8_t* crcPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; - - - unpack_tlv_t unpack_fns[] = - { - { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, - { NFAPI_CRC_INDICATION_REL8_TAG, &pdu->crc_indication_rel8, unpack_crc_indication_rel8_value }, - }; - - if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, crcPduInstanceEnd, 0, 0) == 0) - return 0; - } - - return 1; -} - -static uint8_t unpack_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_crc_indication_t *pNfapiMsg = (nfapi_crc_indication_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_CRC_INDICATION_BODY_TAG, &pNfapiMsg->crc_indication_body, &unpack_crc_indication_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_rx_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_rx_indication_rel8_t* value = (nfapi_rx_indication_rel8_t*)tlv; - - return (pull16(ppReadPackedMsg, &value->length, end) && - pull16(ppReadPackedMsg, &value->offset, end) && - pull8(ppReadPackedMsg, &value->ul_cqi, end) && - pull16(ppReadPackedMsg, &value->timing_advance, end)); -} -static uint8_t unpack_rx_indication_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_rx_indication_rel9_t* value = (nfapi_rx_indication_rel9_t*)tlv; - return (pull16(ppReadPackedMsg, &value->timing_advance_r9, end)); -} - -static uint8_t unpack_rx_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_rx_indication_body_t* value = (nfapi_rx_indication_body_t*)tlv; - - // the rxBodyEnd points to the end of the cqi PDU's - uint8_t* rxBodyEnd = *ppReadPackedMsg + value->tl.length; - uint8_t* rxPduEnd = rxBodyEnd; - - uint8_t* numberOfPdusAddress = *ppReadPackedMsg; - - if(rxBodyEnd > end) - { - // pdu end is past buffer end - return 0; - } - - if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) - return 0; - - if(value->number_of_pdus > NFAPI_RX_IND_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of rx ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_RX_IND_MAX_PDU); - return 0; - } - - if(value->number_of_pdus > 0) - { - value->rx_pdu_list = (nfapi_rx_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_rx_indication_pdu_t) * value->number_of_pdus, config); - if(value->rx_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate rx ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); - return 0; - } - } - else - { - value->rx_pdu_list = 0; - } - - uint8_t i = 0; - nfapi_rx_indication_pdu_t* pdu = 0; - while((uint8_t*)(*ppReadPackedMsg) < rxBodyEnd && (uint8_t*)(*ppReadPackedMsg) < rxPduEnd) - { - nfapi_tl_t generic_tl; - if( unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) - return 0; - - switch(generic_tl.tag) - { - case NFAPI_RX_UE_INFORMATION_TAG: - { - pdu = &(value->rx_pdu_list[i++]); - pdu->rx_ue_information.tl = generic_tl; - if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0) - return 0; - } - break; - case NFAPI_RX_INDICATION_REL8_TAG: - { - if(pdu != 0) - { - pdu->rx_indication_rel8.tl = generic_tl; - if(unpack_rx_indication_rel8_value(&pdu->rx_indication_rel8, ppReadPackedMsg, end) == 0) - return 0; - - if(pdu->rx_indication_rel8.offset > 0) - { - // Need to check that the data is within the tlv - if(numberOfPdusAddress + pdu->rx_indication_rel8.offset + pdu->rx_indication_rel8.length <= rxBodyEnd) - { - // If this the first pdu set the rxPduEnd - if(numberOfPdusAddress + pdu->rx_indication_rel8.offset < rxPduEnd) - { - rxPduEnd = numberOfPdusAddress + pdu->rx_indication_rel8.offset; - - if(rxPduEnd > end) - { - // pdu end is past buffer end - return 0; - } - } - } - else - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME: the rx data is outside of the tlv\n"); - } - } - } - } - break; - case NFAPI_RX_INDICATION_REL9_TAG: - { - if(pdu != 0) - { - pdu->rx_indication_rel9.tl = generic_tl; - if(unpack_rx_indication_rel9_value(&pdu->rx_indication_rel9, ppReadPackedMsg, end) == 0) - return 0; - } - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_ULSCH.indication Invalid pdu type %d \n", generic_tl.tag ); - } - break; - } - } - - uint8_t idx = 0; - for(idx = 0; idx < value->number_of_pdus; ++idx) - { - if(value->rx_pdu_list[idx].rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) - { - uint32_t length = value->rx_pdu_list[idx].rx_indication_rel8.length; - value->rx_pdu_list[idx].data = nfapi_p7_allocate(length, config); - if(pullarray8(ppReadPackedMsg, value->rx_pdu_list[idx].data, length, length, end) == 0) - { - return 0; - } - } - } - - return 1; -} - -static uint8_t unpack_rx_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_rx_indication_t *pNfapiMsg = (nfapi_rx_indication_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_RX_INDICATION_BODY_TAG, &pNfapiMsg->rx_indication_body, &unpack_rx_indication_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_preamble_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_preamble_pdu_rel8_t* preamble_pdu_rel8 = (nfapi_preamble_pdu_rel8_t*)tlv; - - return (pull16(ppReadPackedMsg, &preamble_pdu_rel8->rnti, end) && - pull8(ppReadPackedMsg, &preamble_pdu_rel8->preamble, end) && - pull16(ppReadPackedMsg, &preamble_pdu_rel8->timing_advance, end)); -} - -static uint8_t unpack_preamble_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_preamble_pdu_rel9_t* preamble_pdu_rel9 = (nfapi_preamble_pdu_rel9_t*)tlv; - return pull16(ppReadPackedMsg, &preamble_pdu_rel9->timing_advance_r9, end); -} - -static uint8_t unpack_preamble_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_preamble_pdu_rel13_t* preamble_pdu_rel13 = (nfapi_preamble_pdu_rel13_t*)tlv; - return pull8(ppReadPackedMsg, &preamble_pdu_rel13->rach_resource_type, end); -} - -static uint8_t unpack_rach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_rach_indication_body_t* value = (nfapi_rach_indication_body_t*)tlv; - uint8_t* rachBodyEnd = *ppReadPackedMsg + value->tl.length; - - if(rachBodyEnd > end) - return 0; - - if(pull16(ppReadPackedMsg, &value->number_of_preambles, end) == 0) - return 0; - - if(value->number_of_preambles > NFAPI_PREAMBLE_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of preamble du's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_preambles, NFAPI_PREAMBLE_MAX_PDU); - return 0; - } - - if(value->number_of_preambles > 0) - { - value->preamble_list = (nfapi_preamble_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_preamble_pdu_t) * value->number_of_preambles, config); - if(value->preamble_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate preamble pdu list (count:%d)\n", __FUNCTION__, value->number_of_preambles); - return 0; - } - } - else - { - value->preamble_list = 0; - } - - - uint8_t i = 0; - for(i = 0; i < value->number_of_preambles; ++i) - { - nfapi_preamble_pdu_t* pdu = &(value->preamble_list[i]); - - if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) - return 0; - - uint8_t* preamblePduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; - - - unpack_tlv_t unpack_fns[] = - { - { NFAPI_PREAMBLE_REL8_TAG, &pdu->preamble_rel8, unpack_preamble_pdu_rel8_value }, - { NFAPI_PREAMBLE_REL9_TAG, &pdu->preamble_rel9, unpack_preamble_pdu_rel9_value }, - { NFAPI_PREAMBLE_REL13_TAG, &pdu->preamble_rel13, unpack_preamble_pdu_rel13_value }, - }; - - if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, preamblePduInstanceEnd, 0, 0) == 0) - return 0; - } - return 1; -} - -static uint8_t unpack_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_rach_indication_t *pNfapiMsg = (nfapi_rach_indication_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_RACH_INDICATION_BODY_TAG, &pNfapiMsg->rach_indication_body, &unpack_rach_indication_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_srs_indication_fdd_rel8_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_srs_indication_fdd_rel8_t* srs_pdu_fdd_rel8 = (nfapi_srs_indication_fdd_rel8_t*)tlv; - - if(!(pull16(ppReadPackedMsg, &srs_pdu_fdd_rel8->doppler_estimation, end) && - pull16(ppReadPackedMsg, &srs_pdu_fdd_rel8->timing_advance, end) && - pull8(ppReadPackedMsg, &srs_pdu_fdd_rel8->number_of_resource_blocks, end) && - pull8(ppReadPackedMsg, &srs_pdu_fdd_rel8->rb_start, end) && - pullarray8(ppReadPackedMsg, srs_pdu_fdd_rel8->snr, NFAPI_NUM_RB_MAX, srs_pdu_fdd_rel8->number_of_resource_blocks, end))) - return 0; - return 1; -} - -static uint8_t unpack_srs_indication_fdd_rel9_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_srs_indication_fdd_rel9_t* srs_pdu_fdd_rel9 = (nfapi_srs_indication_fdd_rel9_t*)tlv; - return (pull16(ppReadPackedMsg, &srs_pdu_fdd_rel9->timing_advance_r9, end)); -} - -static uint8_t unpack_srs_indication_tdd_rel10_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_srs_indication_ttd_rel10_t* srs_pdu_tdd_rel10 = (nfapi_srs_indication_ttd_rel10_t*)tlv; - return (pull8(ppReadPackedMsg, &srs_pdu_tdd_rel10->uppts_symbol, end)); -} - -static uint8_t unpack_srs_indication_fdd_rel11_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_srs_indication_fdd_rel11_t* srs_pdu_fdd_rel11 = (nfapi_srs_indication_fdd_rel11_t*)tlv; - return ( pull16(ppReadPackedMsg, &srs_pdu_fdd_rel11->ul_rtoa, end)); -} - -static uint8_t unpack_tdd_channel_measurement_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_tdd_channel_measurement_t* value = (nfapi_tdd_channel_measurement_t*)tlv; - - if(!(pull8(ppReadPackedMsg, &value->num_prb_per_subband, end) && - pull8(ppReadPackedMsg, &value->number_of_subbands, end) && - pull8(ppReadPackedMsg, &value->num_atennas, end))) - return 0; - - if(value->number_of_subbands > NFAPI_MAX_NUM_SUBBANDS) - { - // todo : add error - return 0; - } - - if(value->num_atennas > NFAPI_MAX_NUM_PHYSICAL_ANTENNAS) - { - // todo : add error - return 0; - } - - uint8_t idx = 0; - for(idx = 0; idx < value->number_of_subbands; ++idx) - { - if(!(pull8(ppReadPackedMsg, &value->subands[idx].subband_index, end) && - pullarray16(ppReadPackedMsg, value->subands[idx].channel, NFAPI_MAX_NUM_PHYSICAL_ANTENNAS, value->num_atennas, end))) - return 0; - } - - return 1; -} - - -static uint8_t unpack_srs_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_srs_indication_body_t* value = (nfapi_srs_indication_body_t*)tlv; - uint8_t* srsBodyEnd = *ppReadPackedMsg + value->tl.length; - - if(srsBodyEnd > end) - return 0; - - if(pull8(ppReadPackedMsg, &value->number_of_ues, end) == 0) - return 0; - - if(value->number_of_ues > NFAPI_SRS_IND_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of srs ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_ues, NFAPI_SRS_IND_MAX_PDU); - return 0; - } - - if(value->number_of_ues > 0) - { - value->srs_pdu_list = (nfapi_srs_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_srs_indication_pdu_t) * value->number_of_ues, config); - if(value->srs_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate srs ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_ues); - return 0; - } - } - else - { - value->srs_pdu_list = 0; - } - - - - uint8_t i = 0; - for(i = 0; i < value->number_of_ues; ++i) - { - nfapi_srs_indication_pdu_t* pdu = &(value->srs_pdu_list[i]); - - - if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) - return 0; - - uint8_t* srsPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; - - - unpack_tlv_t unpack_fns[] = - { - { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, - { NFAPI_SRS_INDICATION_FDD_REL8_TAG, &pdu->srs_indication_fdd_rel8, unpack_srs_indication_fdd_rel8_value}, - { NFAPI_SRS_INDICATION_FDD_REL9_TAG, &pdu->srs_indication_fdd_rel9, unpack_srs_indication_fdd_rel9_value}, - { NFAPI_SRS_INDICATION_TDD_REL10_TAG, &pdu->srs_indication_tdd_rel10, unpack_srs_indication_tdd_rel10_value}, - { NFAPI_SRS_INDICATION_FDD_REL11_TAG, &pdu->srs_indication_fdd_rel11, unpack_srs_indication_fdd_rel11_value}, - { NFAPI_TDD_CHANNEL_MEASUREMENT_TAG, &pdu->tdd_channel_measurement, unpack_tdd_channel_measurement_value}, - }; - - if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, srsPduInstanceEnd, 0, 0) == 0) - return 0; - } - return 1; -} - -static uint8_t unpack_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_srs_indication_t *pNfapiMsg = (nfapi_srs_indication_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_SRS_INDICATION_BODY_TAG, &pNfapiMsg->srs_indication_body, &unpack_srs_indication_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - - -static uint8_t unpack_sr_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_sr_indication_body_t* value = (nfapi_sr_indication_body_t*)tlv; - uint8_t* srBodyEnd = *ppReadPackedMsg + value->tl.length; - - if(srBodyEnd > end) - return 0; - - if(pull16(ppReadPackedMsg, &value->number_of_srs, end) == 0) - return 0; - - if(value->number_of_srs > NFAPI_SR_IND_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of sr ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_srs, NFAPI_SR_IND_MAX_PDU); - return 0; - } - - if(value->number_of_srs > 0) - { - value->sr_pdu_list = (nfapi_sr_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_sr_indication_pdu_t) * value->number_of_srs, config); - if(value->sr_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate sr ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_srs); - return 0; - } - } - else - { - value->sr_pdu_list = 0; - } - - uint8_t i = 0; - for(i = 0; i < value->number_of_srs; ++i) - { - nfapi_sr_indication_pdu_t* pdu = &(value->sr_pdu_list[i]); - - if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) - return 0; - - uint8_t* srPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; - - - unpack_tlv_t unpack_fns[] = - { - { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, - { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, unpack_ul_cqi_information_value }, - }; - - if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, srPduInstanceEnd, 0, 0) == 0) - return 0; - } - - return 1; - -} - -static int unpack_sr_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_sr_indication_t *pNfapiMsg = (nfapi_sr_indication_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_SR_INDICATION_BODY_TAG, &pNfapiMsg->sr_indication_body, &unpack_sr_indication_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} -static uint8_t unpack_cqi_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_cqi_indication_rel8_t* cqi_pdu_rel8 = (nfapi_cqi_indication_rel8_t*)tlv; - - return (pull16(ppReadPackedMsg, &cqi_pdu_rel8->length, end) && - pull16(ppReadPackedMsg, &cqi_pdu_rel8->data_offset, end) && - pull8(ppReadPackedMsg, &cqi_pdu_rel8->ul_cqi, end) && - pull8(ppReadPackedMsg, &cqi_pdu_rel8->ri, end) && - pull16(ppReadPackedMsg, &cqi_pdu_rel8->timing_advance, end)); - -} - -static uint8_t unpack_cqi_indication_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_cqi_indication_rel9_t* cqi_pdu_rel9 = (nfapi_cqi_indication_rel9_t*)tlv; - - if(!(pull16(ppReadPackedMsg, &cqi_pdu_rel9->length, end) && - pull16(ppReadPackedMsg, &cqi_pdu_rel9->data_offset, end) && - pull8(ppReadPackedMsg, &cqi_pdu_rel9->ul_cqi, end) && - pull8(ppReadPackedMsg, &cqi_pdu_rel9->number_of_cc_reported, end))) - return 0; - - if(cqi_pdu_rel9->number_of_cc_reported > NFAPI_CC_MAX) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : out of bound array\n"); - return 0; - } - - if(!(pullarray8(ppReadPackedMsg, cqi_pdu_rel9->ri, NFAPI_CC_MAX, cqi_pdu_rel9->number_of_cc_reported, end) && - pull16(ppReadPackedMsg, &cqi_pdu_rel9->timing_advance, end) && - pull16(ppReadPackedMsg, &cqi_pdu_rel9->timing_advance_r9, end))) - return 0; - - return 1; -} - -static uint8_t unpack_cqi_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_cqi_indication_body_t* value = (nfapi_cqi_indication_body_t*)tlv; - - // the cqiBodyEnd points to the end of the cqi PDU's - uint8_t* cqiBodyEnd = *ppReadPackedMsg + value->tl.length; - - //uint8_t* cqiPduEnd = cqiBodyEnd; - //uint8_t* numberOfPdusAddress = *ppReadPackedMsg; - - if(cqiBodyEnd > end) - return 0; - - if(pull16(ppReadPackedMsg, &value->number_of_cqis, end) == 0) - return 0; - - if(value->number_of_cqis > NFAPI_CQI_IND_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of cqi ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_cqis, NFAPI_CQI_IND_MAX_PDU); - return -1; - } - - if(value->number_of_cqis > 0) - { - value->cqi_pdu_list = (nfapi_cqi_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_cqi_indication_pdu_t) * value->number_of_cqis, config); - if(value->cqi_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate cqi ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_cqis); - return 0; - } - } - else - { - value->cqi_pdu_list = 0; - } - - if(value->number_of_cqis > 0) - { - value->cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_cqi_indication_raw_pdu_t) * value->number_of_cqis, config); - if(value->cqi_raw_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate raw cqi ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_cqis); - return 0; - } - } - else - { - value->cqi_raw_pdu_list = 0; - } - - uint8_t i = 0; - for(i = 0; i < value->number_of_cqis; ++i) - { - nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); - memset(pdu, 0, sizeof(nfapi_cqi_indication_pdu_t)); - - if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) - return 0; - - uint8_t* cqiPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; - - - while((uint8_t*)(*ppReadPackedMsg) < cqiPduInstanceEnd) - { - nfapi_tl_t generic_tl; - if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) - return 0; - - switch(generic_tl.tag) - { - case NFAPI_RX_UE_INFORMATION_TAG: - pdu->rx_ue_information.tl = generic_tl; - if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0) - return 0; - break; - case NFAPI_CQI_INDICATION_REL8_TAG: - pdu->cqi_indication_rel8.tl = generic_tl; - if(unpack_cqi_indication_rel8_value(&pdu->cqi_indication_rel8, ppReadPackedMsg, end) == 0) - return 0; - - break; - case NFAPI_CQI_INDICATION_REL9_TAG: - pdu->cqi_indication_rel9.tl = generic_tl; - if(unpack_cqi_indication_rel9_value(&pdu->cqi_indication_rel9, ppReadPackedMsg, end) == 0) - return 0; - - break; - case NFAPI_UL_CQI_INFORMATION_TAG: - pdu->ul_cqi_information.tl = generic_tl; - if(unpack_ul_cqi_information_value(&pdu->ul_cqi_information, ppReadPackedMsg, end) == 0) - return 0; - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_CQI.indication Invalid pdu type %d \n", generic_tl.tag ); - } - break; - - }; - } - } - - uint8_t idx = 0; - for(idx = 0; idx < value->number_of_cqis; ++idx) - { - if(value->cqi_pdu_list[idx].cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) - { - if(pullarray8(ppReadPackedMsg, &(value->cqi_raw_pdu_list[idx].pdu[0]), NFAPI_CQI_RAW_MAX_LEN, value->cqi_pdu_list[idx].cqi_indication_rel8.length, end) == 0) - return 0; - } - else if(value->cqi_pdu_list[idx].cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) - { - if(pullarray8(ppReadPackedMsg, &(value->cqi_raw_pdu_list[idx].pdu[0]), NFAPI_CQI_RAW_MAX_LEN, value->cqi_pdu_list[idx].cqi_indication_rel9.length, end) == 0) - return 0; - } - } - - - return 1; - -} - -static uint8_t unpack_cqi_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_cqi_indication_t *pNfapiMsg = (nfapi_cqi_indication_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_CQI_INDICATION_BODY_TAG, &pNfapiMsg->cqi_indication_body, &unpack_cqi_indication_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} -static uint8_t unpack_lbt_pdsch_req_pdu_rel13_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_lbt_pdsch_req_pdu_rel13_t* value = (nfapi_lbt_pdsch_req_pdu_rel13_t*)tlv; - - return (pull32(ppReadPackedMsg, &value->handle, end) && - pull32(ppReadPackedMsg, &value->mp_cca, end) && - pull32(ppReadPackedMsg, &value->n_cca, end) && - pull32(ppReadPackedMsg, &value->offset, end) && - pull32(ppReadPackedMsg, &value->lte_txop_sf, end) && - pull16(ppReadPackedMsg, &value->txop_sfn_sf_end, end) && - pull32(ppReadPackedMsg, &value->lbt_mode, end)); -} - -static uint8_t unpack_lbt_drs_req_pdu_rel13_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_lbt_drs_req_pdu_rel13_t* value = (nfapi_lbt_drs_req_pdu_rel13_t*)tlv; - - return (pull32(ppReadPackedMsg, &value->handle, end) && - pull32(ppReadPackedMsg, &value->offset, end) && - pull16(ppReadPackedMsg, &value->sfn_sf_end, end) && - pull32(ppReadPackedMsg, &value->lbt_mode, end)); -} - - -static uint8_t unpack_lbt_config_request_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_lbt_dl_config_request_body_t* value = (nfapi_lbt_dl_config_request_body_t*)tlv; - - if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) - return 0; - - if(value->number_of_pdus > NFAPI_LBT_DL_CONFIG_REQ_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of lbt dl config pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_LBT_DL_CONFIG_REQ_MAX_PDU); - return 0; - } - - if(value->number_of_pdus) - { - value->lbt_dl_config_req_pdu_list = (nfapi_lbt_dl_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_lbt_dl_config_request_pdu_t) * value->number_of_pdus, config); - if(value->lbt_dl_config_req_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate lbt dl config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); - return 0; - } - } - else - { - value->lbt_dl_config_req_pdu_list = 0; - } - - - uint16_t i; - uint16_t total_number_of_pdus = value->number_of_pdus; - for(i = 0; i < total_number_of_pdus; ++i) - { - nfapi_lbt_dl_config_request_pdu_t* pdu = &(value->lbt_dl_config_req_pdu_list[i]); - - if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && - pull8(ppReadPackedMsg, &pdu->pdu_size, end))) - return 0; - - uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; - - if(packedPduEnd > end) - return 0; - - switch(pdu->pdu_type) - { - case NFAPI_LBT_DL_CONFIG_REQUEST_PDSCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_LBT_PDSCH_REQ_PDU_REL13_TAG, &pdu->lbt_pdsch_req_pdu.lbt_pdsch_req_pdu_rel13, &unpack_lbt_pdsch_req_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_LBT_DL_CONFIG_REQUEST_DRS_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_LBT_DRS_REQ_PDU_REL13_TAG, &pdu->lbt_drs_req_pdu.lbt_drs_req_pdu_rel13, &unpack_lbt_drs_req_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - default: - NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL_CONFIG.request body invalid pdu type %d\n", pdu->pdu_type); - return 0; - } - } - - return 1; -} -static uint8_t unpack_lbt_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_lbt_dl_config_request_t *pNfapiMsg = (nfapi_lbt_dl_config_request_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_LBT_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->lbt_dl_config_request_body, &unpack_lbt_config_request_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_lbt_pdsch_rsp_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_lbt_pdsch_rsp_pdu_rel13_t* value = (nfapi_lbt_pdsch_rsp_pdu_rel13_t*)tlv; - - return (pull32(ppReadPackedMsg, &value->handle, end) && - pull32(ppReadPackedMsg, &value->result, end) && - pull32(ppReadPackedMsg, &value->lte_txop_symbols, end) && - pull32(ppReadPackedMsg, &value->initial_partial_sf, end)); - -} -static uint8_t unpack_lbt_drs_rsp_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_lbt_drs_rsp_pdu_rel13_t* value = (nfapi_lbt_drs_rsp_pdu_rel13_t*)tlv; - - return (pull32(ppReadPackedMsg, &value->handle, end) && - pull32(ppReadPackedMsg, &value->result, end)); -} - -static uint8_t unpack_lbt_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_lbt_dl_indication_body_t* value = (nfapi_lbt_dl_indication_body_t*)tlv; - - if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) - return 0; - - if(value->number_of_pdus > NFAPI_LBT_IND_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of lbt dl ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_LBT_IND_MAX_PDU); - return 0; - } - - if(value->number_of_pdus > 0) - { - value->lbt_indication_pdu_list = (nfapi_lbt_dl_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_lbt_dl_indication_pdu_t) * value->number_of_pdus, config); - if(value->lbt_indication_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate lbt dl ind config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); - return 0; - } - } - else - { - value->lbt_indication_pdu_list = 0; - } - - uint16_t i; - uint16_t total_number_of_pdus = value->number_of_pdus; - for(i = 0; i < total_number_of_pdus; ++i) - { - nfapi_lbt_dl_indication_pdu_t* pdu = &(value->lbt_indication_pdu_list[i]); - - if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && - pull8(ppReadPackedMsg, &pdu->pdu_size, end))) - return 0; - - uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; - - if(packedPduEnd > end) - return 0; - - switch(pdu->pdu_type) - { - case NFAPI_LBT_DL_RSP_PDSCH_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG, &pdu->lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13, &unpack_lbt_pdsch_rsp_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - case NFAPI_LBT_DL_RSP_DRS_PDU_TYPE: - { - unpack_tlv_t unpack_fns[] = - { - { NFAPI_LBT_DRS_RSP_PDU_REL13_TAG, &pdu->lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13, &unpack_lbt_drs_rsp_pdu_rel13_value}, - }; - - unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); - } - break; - default: - NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL.indication body invalid pdu type %d\n", pdu->pdu_type); - return 0; - } - } - - return 1; -} -static uint8_t unpack_lbt_dl_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_lbt_dl_indication_t *pNfapiMsg = (nfapi_lbt_dl_indication_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_LBT_DL_INDICATION_BODY_TAG, &pNfapiMsg->lbt_dl_indication_body, &unpack_lbt_indication_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_nb_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_nb_harq_indication_fdd_rel13_t* value = (nfapi_nb_harq_indication_fdd_rel13_t*)tlv; - return (pull8(ppReadPackedMsg, &value->harq_tb1, end)); -} - - -static uint8_t unpack_nb_harq_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_nb_harq_indication_body_t* value = (nfapi_nb_harq_indication_body_t*)tlv; - uint8_t* nbharqBodyEnd = *ppReadPackedMsg + value->tl.length; - - if(nbharqBodyEnd > end) - return 0; - - if(pull16(ppReadPackedMsg, &value->number_of_harqs, end) == 0) - return 0; - - if(value->number_of_harqs > NFAPI_HARQ_IND_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of harq ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_harqs, NFAPI_HARQ_IND_MAX_PDU); - return 0; - } - - value->nb_harq_pdu_list = (nfapi_nb_harq_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_nb_harq_indication_pdu_t) * value->number_of_harqs, config); - if(value->nb_harq_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_harqs); - return 0; - } - - uint8_t i = 0; - for(i = 0; i < value->number_of_harqs; ++i) - { - nfapi_nb_harq_indication_pdu_t* pdu = &(value->nb_harq_pdu_list[i]); - if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) - return 0; - - uint8_t* harqPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; - - unpack_tlv_t unpack_fns[] = - { - { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, - { NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG, &pdu->nb_harq_indication_fdd_rel13, &unpack_nb_harq_indication_fdd_rel13_value}, - { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, &unpack_ul_cqi_information_value} - }; - - if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, harqPduInstanceEnd, 0, 0) == 0) - return 0; - - } - - return 1; -} - -static uint8_t unpack_nb_harq_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_nb_harq_indication_t *pNfapiMsg = (nfapi_nb_harq_indication_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_NB_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->nb_harq_indication_body, &unpack_nb_harq_indication_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_nrach_indication_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) -{ - nfapi_nrach_indication_pdu_rel13_t* value = (nfapi_nrach_indication_pdu_rel13_t*)tlv; - - return (pull16(ppReadPackedMsg, &value->rnti, end) && - pull8(ppReadPackedMsg, &value->initial_sc, end) && - pull16(ppReadPackedMsg, &value->timing_advance, end) && - pull8(ppReadPackedMsg, &value->nrach_ce_level, end)); -} - +static uint8_t unpack_harq_indication_tdd_harq_data_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_harq_data_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_bundling_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->value_0, end) && + pull8(ppReadPackedMsg, &value->value_1, end)); +} + +static uint8_t unpack_harq_indication_tdd_harq_data_multiplexing(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_harq_data_multiplexing_t* value = (nfapi_harq_indication_tdd_harq_data_multiplexing_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->value_0, end) && + pull8(ppReadPackedMsg, &value->value_1, end) && + pull8(ppReadPackedMsg, &value->value_2, end) && + pull8(ppReadPackedMsg, &value->value_3, end)); +} +static uint8_t unpack_harq_indication_tdd_harq_data_special_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_harq_data_special_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_special_bundling_t*)tlv; + return ( pull8(ppReadPackedMsg, &value->value_0, end)); +} +static uint8_t unpack_harq_indication_tdd_harq_data(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_harq_data_t* value = (nfapi_harq_indication_tdd_harq_data_t*)tlv; + return (pull8(ppReadPackedMsg, &value->value_0, end)); +} + +static uint8_t unpack_harq_indication_tdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel8_t* value = (nfapi_harq_indication_tdd_rel8_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->mode, end) && + pull8(ppReadPackedMsg, &value->number_of_ack_nack, end))) + return 0; + + uint8_t result = 0; + switch(value->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = unpack_harq_indication_tdd_harq_data_bundling(&value->harq_data.bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = unpack_harq_indication_tdd_harq_data_multiplexing(&value->harq_data.multiplex, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data.special_bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + result = 1; + break; + default: + // TODO add error message + return 0; + break; + } + return result; +} + +static uint8_t unpack_harq_indication_tdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel9_t* value = (nfapi_harq_indication_tdd_rel9_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->mode, end) && + pull8(ppReadPackedMsg, &value->number_of_ack_nack, end))) + return 0; + + if(value->number_of_ack_nack > NFAPI_MAX_NUMBER_ACK_NACK_TDD) + { + // TODO : add error message + return 0; + } + + uint16_t idx = 0; + for(idx = 0; idx < value->number_of_ack_nack; ++idx) + { + uint8_t result = 0; + switch(value->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].multiplex, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data[idx].special_bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].channel_selection, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_3, ppReadPackedMsg, end); + break; + default: + // TODO add error message + return 0; + break; + } + + if(result == 0) + return 0; + } + return 1; +} + +static uint8_t unpack_harq_indication_tdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_tdd_rel13_t* value = (nfapi_harq_indication_tdd_rel13_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->mode, end) && + pull16(ppReadPackedMsg, &value->number_of_ack_nack, end))) + return 0; + + if(value->number_of_ack_nack > NFAPI_MAX_NUMBER_ACK_NACK_TDD) + { + // TODO : add error message + return 0; + } + + uint16_t idx = 0; + for(idx = 0; idx < value->number_of_ack_nack; ++idx) + { + uint8_t result = 0; + switch(value->mode) + { + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_BUNDLING: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_MULIPLEXING: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].multiplex, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_SPECIAL_BUNDLING: + result = unpack_harq_indication_tdd_harq_data_special_bundling(&value->harq_data[idx].special_bundling, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_CHANNEL_SELECTION: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].channel_selection, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_3: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_3, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_4: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_4, ppReadPackedMsg, end); + break; + case NFAPI_HARQ_INDICATION_TDD_HARQ_ACK_NACK_FORMAT_FORMAT_5: + result = unpack_harq_indication_tdd_harq_data(&value->harq_data[idx].format_5, ppReadPackedMsg, end); + break; + default: + // TODO add error message + return 0; + break; + } + + if(result == 0) + return 0; + } + return 1; +} + +static uint8_t unpack_harq_indication_fdd_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel8_t* value = (nfapi_harq_indication_fdd_rel8_t*)tlv; + return (pull8(ppReadPackedMsg, &value->harq_tb1, end) && + pull8(ppReadPackedMsg, &value->harq_tb2, end)); +} + +static uint8_t unpack_harq_indication_fdd_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel9_t* value = (nfapi_harq_indication_fdd_rel9_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->mode, end) && + pull8(ppReadPackedMsg, &value->number_of_ack_nack, end) && + pullarray8(ppReadPackedMsg, value->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL9_MAX, value->number_of_ack_nack, end)); +} + +static uint8_t unpack_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_harq_indication_fdd_rel13_t* value = (nfapi_harq_indication_fdd_rel13_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->mode, end) && + pull16(ppReadPackedMsg, &value->number_of_ack_nack, end) && + pullarray8(ppReadPackedMsg, value->harq_tb_n, NFAPI_HARQ_ACK_NACK_REL13_MAX, value->number_of_ack_nack, end)); +} + +static uint8_t unpack_ul_cqi_information_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_ul_cqi_information_t* value = (nfapi_ul_cqi_information_t*)tlv; + + return (pull8(ppReadPackedMsg, &value->ul_cqi, end) && + pull8(ppReadPackedMsg, &value->channel, end)); +} + + + +static uint8_t unpack_harq_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_harq_indication_body_t* value = (nfapi_harq_indication_body_t*)tlv; + uint8_t* harqBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(harqBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_harqs, end) == 0) + return 0; + + if(value->number_of_harqs > NFAPI_HARQ_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of harq ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_harqs, NFAPI_HARQ_IND_MAX_PDU); + return 0; + } + + value->harq_pdu_list = (nfapi_harq_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_harq_indication_pdu_t) * value->number_of_harqs, config); + if(value->harq_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_harqs); + return 0; + } + + uint8_t i = 0; + for(i = 0; i < value->number_of_harqs; ++i) + { + nfapi_harq_indication_pdu_t* pdu = &(value->harq_pdu_list[i]); + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* harqPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, + { NFAPI_HARQ_INDICATION_TDD_REL8_TAG, &pdu->harq_indication_tdd_rel8, &unpack_harq_indication_tdd_rel8_value}, + { NFAPI_HARQ_INDICATION_TDD_REL9_TAG, &pdu->harq_indication_tdd_rel9, &unpack_harq_indication_tdd_rel9_value}, + { NFAPI_HARQ_INDICATION_TDD_REL13_TAG, &pdu->harq_indication_tdd_rel13, &unpack_harq_indication_tdd_rel13_value}, + { NFAPI_HARQ_INDICATION_FDD_REL8_TAG, &pdu->harq_indication_fdd_rel8, &unpack_harq_indication_fdd_rel8_value}, + { NFAPI_HARQ_INDICATION_FDD_REL9_TAG, &pdu->harq_indication_fdd_rel9, &unpack_harq_indication_fdd_rel9_value}, + { NFAPI_HARQ_INDICATION_FDD_REL13_TAG, &pdu->harq_indication_fdd_rel13, &unpack_harq_indication_fdd_rel13_value}, + { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, &unpack_ul_cqi_information_value} + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, harqPduInstanceEnd, 0, 0) == 0) + return 0; + + } + + return 1; +} + +static uint8_t unpack_harq_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_harq_indication_t *pNfapiMsg = (nfapi_harq_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->harq_indication_body, &unpack_harq_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_crc_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_crc_indication_rel8_t* crc_pdu_rel8 = (nfapi_crc_indication_rel8_t*)tlv; + return ( pull8(ppReadPackedMsg, &crc_pdu_rel8->crc_flag, end) ); +} + +static uint8_t unpack_crc_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_crc_indication_body_t* value = (nfapi_crc_indication_body_t*)tlv; + uint8_t* crcBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(crcBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_crcs, end) == 0) + return 0; + + if(value->number_of_crcs > NFAPI_CRC_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of crc ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_crcs, NFAPI_CRC_IND_MAX_PDU); + return 0; + } + + if(value->number_of_crcs > 0) + { + value->crc_pdu_list = (nfapi_crc_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_crc_indication_pdu_t) * value->number_of_crcs, config); + if(value->crc_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate crc ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_crcs); + return 0; + } + } + else + { + value->crc_pdu_list = 0; + } + + + uint8_t i = 0; + for(i = 0; i < value->number_of_crcs; ++i) + { + nfapi_crc_indication_pdu_t* pdu = &(value->crc_pdu_list[i]); + + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* crcPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, + { NFAPI_CRC_INDICATION_REL8_TAG, &pdu->crc_indication_rel8, unpack_crc_indication_rel8_value }, + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, crcPduInstanceEnd, 0, 0) == 0) + return 0; + } + + return 1; +} + +static uint8_t unpack_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_crc_indication_t *pNfapiMsg = (nfapi_crc_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_CRC_INDICATION_BODY_TAG, &pNfapiMsg->crc_indication_body, &unpack_crc_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_rx_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_rx_indication_rel8_t* value = (nfapi_rx_indication_rel8_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->length, end) && + pull16(ppReadPackedMsg, &value->offset, end) && + pull8(ppReadPackedMsg, &value->ul_cqi, end) && + pull16(ppReadPackedMsg, &value->timing_advance, end)); +} +static uint8_t unpack_rx_indication_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_rx_indication_rel9_t* value = (nfapi_rx_indication_rel9_t*)tlv; + return (pull16(ppReadPackedMsg, &value->timing_advance_r9, end)); +} + +static uint8_t unpack_rx_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_rx_indication_body_t* value = (nfapi_rx_indication_body_t*)tlv; + + // the rxBodyEnd points to the end of the cqi PDU's + uint8_t* rxBodyEnd = *ppReadPackedMsg + value->tl.length; + uint8_t* rxPduEnd = rxBodyEnd; + + uint8_t* numberOfPdusAddress = *ppReadPackedMsg; + + if(rxBodyEnd > end) + { + // pdu end is past buffer end + return 0; + } + + if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) + return 0; + + if(value->number_of_pdus > NFAPI_RX_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of rx ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_RX_IND_MAX_PDU); + return 0; + } + + if(value->number_of_pdus > 0) + { + value->rx_pdu_list = (nfapi_rx_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_rx_indication_pdu_t) * value->number_of_pdus, config); + if(value->rx_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate rx ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); + return 0; + } + } + else + { + value->rx_pdu_list = 0; + } + + uint8_t i = 0; + nfapi_rx_indication_pdu_t* pdu = 0; + while((uint8_t*)(*ppReadPackedMsg) < rxBodyEnd && (uint8_t*)(*ppReadPackedMsg) < rxPduEnd) + { + nfapi_tl_t generic_tl; + if( unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + switch(generic_tl.tag) + { + case NFAPI_RX_UE_INFORMATION_TAG: + { + pdu = &(value->rx_pdu_list[i++]); + pdu->rx_ue_information.tl = generic_tl; + if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0) + return 0; + } + break; + case NFAPI_RX_INDICATION_REL8_TAG: + { + if(pdu != 0) + { + pdu->rx_indication_rel8.tl = generic_tl; + if(unpack_rx_indication_rel8_value(&pdu->rx_indication_rel8, ppReadPackedMsg, end) == 0) + return 0; + + if(pdu->rx_indication_rel8.offset > 0) + { + // Need to check that the data is within the tlv + if(numberOfPdusAddress + pdu->rx_indication_rel8.offset + pdu->rx_indication_rel8.length <= rxBodyEnd) + { + // If this the first pdu set the rxPduEnd + if(numberOfPdusAddress + pdu->rx_indication_rel8.offset < rxPduEnd) + { + rxPduEnd = numberOfPdusAddress + pdu->rx_indication_rel8.offset; + + if(rxPduEnd > end) + { + // pdu end is past buffer end + return 0; + } + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME: the rx data is outside of the tlv\n"); + } + } + } + } + break; + case NFAPI_RX_INDICATION_REL9_TAG: + { + if(pdu != 0) + { + pdu->rx_indication_rel9.tl = generic_tl; + if(unpack_rx_indication_rel9_value(&pdu->rx_indication_rel9, ppReadPackedMsg, end) == 0) + return 0; + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_ULSCH.indication Invalid pdu type %d \n", generic_tl.tag ); + } + break; + } + } + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_pdus; ++idx) + { + if(value->rx_pdu_list[idx].rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) + { + uint32_t length = value->rx_pdu_list[idx].rx_indication_rel8.length; + value->rx_pdu_list[idx].data = nfapi_p7_allocate(length, config); + if(pullarray8(ppReadPackedMsg, value->rx_pdu_list[idx].data, length, length, end) == 0) + { + return 0; + } + } + } + + return 1; +} + +static uint8_t unpack_rx_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_rx_indication_t *pNfapiMsg = (nfapi_rx_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_RX_INDICATION_BODY_TAG, &pNfapiMsg->rx_indication_body, &unpack_rx_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_preamble_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel8_t* preamble_pdu_rel8 = (nfapi_preamble_pdu_rel8_t*)tlv; + + return (pull16(ppReadPackedMsg, &preamble_pdu_rel8->rnti, end) && + pull8(ppReadPackedMsg, &preamble_pdu_rel8->preamble, end) && + pull16(ppReadPackedMsg, &preamble_pdu_rel8->timing_advance, end)); +} + +static uint8_t unpack_preamble_pdu_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel9_t* preamble_pdu_rel9 = (nfapi_preamble_pdu_rel9_t*)tlv; + return pull16(ppReadPackedMsg, &preamble_pdu_rel9->timing_advance_r9, end); +} + +static uint8_t unpack_preamble_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_preamble_pdu_rel13_t* preamble_pdu_rel13 = (nfapi_preamble_pdu_rel13_t*)tlv; + return pull8(ppReadPackedMsg, &preamble_pdu_rel13->rach_resource_type, end); +} + +static uint8_t unpack_rach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_rach_indication_body_t* value = (nfapi_rach_indication_body_t*)tlv; + uint8_t* rachBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(rachBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_preambles, end) == 0) + return 0; + + if(value->number_of_preambles > NFAPI_PREAMBLE_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of preamble du's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_preambles, NFAPI_PREAMBLE_MAX_PDU); + return 0; + } + + if(value->number_of_preambles > 0) + { + value->preamble_list = (nfapi_preamble_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_preamble_pdu_t) * value->number_of_preambles, config); + if(value->preamble_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate preamble pdu list (count:%d)\n", __FUNCTION__, value->number_of_preambles); + return 0; + } + } + else + { + value->preamble_list = 0; + } + + + uint8_t i = 0; + for(i = 0; i < value->number_of_preambles; ++i) + { + nfapi_preamble_pdu_t* pdu = &(value->preamble_list[i]); + + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* preamblePduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_PREAMBLE_REL8_TAG, &pdu->preamble_rel8, unpack_preamble_pdu_rel8_value }, + { NFAPI_PREAMBLE_REL9_TAG, &pdu->preamble_rel9, unpack_preamble_pdu_rel9_value }, + { NFAPI_PREAMBLE_REL13_TAG, &pdu->preamble_rel13, unpack_preamble_pdu_rel13_value }, + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, preamblePduInstanceEnd, 0, 0) == 0) + return 0; + } + return 1; +} + +static uint8_t unpack_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_rach_indication_t *pNfapiMsg = (nfapi_rach_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_RACH_INDICATION_BODY_TAG, &pNfapiMsg->rach_indication_body, &unpack_rach_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_srs_indication_fdd_rel8_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel8_t* srs_pdu_fdd_rel8 = (nfapi_srs_indication_fdd_rel8_t*)tlv; + + if(!(pull16(ppReadPackedMsg, &srs_pdu_fdd_rel8->doppler_estimation, end) && + pull16(ppReadPackedMsg, &srs_pdu_fdd_rel8->timing_advance, end) && + pull8(ppReadPackedMsg, &srs_pdu_fdd_rel8->number_of_resource_blocks, end) && + pull8(ppReadPackedMsg, &srs_pdu_fdd_rel8->rb_start, end) && + pullarray8(ppReadPackedMsg, srs_pdu_fdd_rel8->snr, NFAPI_NUM_RB_MAX, srs_pdu_fdd_rel8->number_of_resource_blocks, end))) + return 0; + return 1; +} + +static uint8_t unpack_srs_indication_fdd_rel9_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel9_t* srs_pdu_fdd_rel9 = (nfapi_srs_indication_fdd_rel9_t*)tlv; + return (pull16(ppReadPackedMsg, &srs_pdu_fdd_rel9->timing_advance_r9, end)); +} + +static uint8_t unpack_srs_indication_tdd_rel10_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_srs_indication_ttd_rel10_t* srs_pdu_tdd_rel10 = (nfapi_srs_indication_ttd_rel10_t*)tlv; + return (pull8(ppReadPackedMsg, &srs_pdu_tdd_rel10->uppts_symbol, end)); +} + +static uint8_t unpack_srs_indication_fdd_rel11_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_srs_indication_fdd_rel11_t* srs_pdu_fdd_rel11 = (nfapi_srs_indication_fdd_rel11_t*)tlv; + return ( pull16(ppReadPackedMsg, &srs_pdu_fdd_rel11->ul_rtoa, end)); +} + +static uint8_t unpack_tdd_channel_measurement_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_tdd_channel_measurement_t* value = (nfapi_tdd_channel_measurement_t*)tlv; + + if(!(pull8(ppReadPackedMsg, &value->num_prb_per_subband, end) && + pull8(ppReadPackedMsg, &value->number_of_subbands, end) && + pull8(ppReadPackedMsg, &value->num_atennas, end))) + return 0; + + if(value->number_of_subbands > NFAPI_MAX_NUM_SUBBANDS) + { + // todo : add error + return 0; + } + + if(value->num_atennas > NFAPI_MAX_NUM_PHYSICAL_ANTENNAS) + { + // todo : add error + return 0; + } + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_subbands; ++idx) + { + if(!(pull8(ppReadPackedMsg, &value->subands[idx].subband_index, end) && + pullarray16(ppReadPackedMsg, value->subands[idx].channel, NFAPI_MAX_NUM_PHYSICAL_ANTENNAS, value->num_atennas, end))) + return 0; + } + + return 1; +} + + +static uint8_t unpack_srs_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_srs_indication_body_t* value = (nfapi_srs_indication_body_t*)tlv; + uint8_t* srsBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(srsBodyEnd > end) + return 0; + + if(pull8(ppReadPackedMsg, &value->number_of_ues, end) == 0) + return 0; + + if(value->number_of_ues > NFAPI_SRS_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of srs ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_ues, NFAPI_SRS_IND_MAX_PDU); + return 0; + } + + if(value->number_of_ues > 0) + { + value->srs_pdu_list = (nfapi_srs_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_srs_indication_pdu_t) * value->number_of_ues, config); + if(value->srs_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate srs ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_ues); + return 0; + } + } + else + { + value->srs_pdu_list = 0; + } + + + + uint8_t i = 0; + for(i = 0; i < value->number_of_ues; ++i) + { + nfapi_srs_indication_pdu_t* pdu = &(value->srs_pdu_list[i]); + + + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* srsPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, + { NFAPI_SRS_INDICATION_FDD_REL8_TAG, &pdu->srs_indication_fdd_rel8, unpack_srs_indication_fdd_rel8_value}, + { NFAPI_SRS_INDICATION_FDD_REL9_TAG, &pdu->srs_indication_fdd_rel9, unpack_srs_indication_fdd_rel9_value}, + { NFAPI_SRS_INDICATION_TDD_REL10_TAG, &pdu->srs_indication_tdd_rel10, unpack_srs_indication_tdd_rel10_value}, + { NFAPI_SRS_INDICATION_FDD_REL11_TAG, &pdu->srs_indication_fdd_rel11, unpack_srs_indication_fdd_rel11_value}, + { NFAPI_TDD_CHANNEL_MEASUREMENT_TAG, &pdu->tdd_channel_measurement, unpack_tdd_channel_measurement_value}, + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, srsPduInstanceEnd, 0, 0) == 0) + return 0; + } + return 1; +} + +static uint8_t unpack_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_srs_indication_t *pNfapiMsg = (nfapi_srs_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_SRS_INDICATION_BODY_TAG, &pNfapiMsg->srs_indication_body, &unpack_srs_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + + +static uint8_t unpack_sr_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_sr_indication_body_t* value = (nfapi_sr_indication_body_t*)tlv; + uint8_t* srBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(srBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_srs, end) == 0) + return 0; + + if(value->number_of_srs > NFAPI_SR_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of sr ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_srs, NFAPI_SR_IND_MAX_PDU); + return 0; + } + + if(value->number_of_srs > 0) + { + value->sr_pdu_list = (nfapi_sr_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_sr_indication_pdu_t) * value->number_of_srs, config); + if(value->sr_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate sr ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_srs); + return 0; + } + } + else + { + value->sr_pdu_list = 0; + } + + uint8_t i = 0; + for(i = 0; i < value->number_of_srs; ++i) + { + nfapi_sr_indication_pdu_t* pdu = &(value->sr_pdu_list[i]); + + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* srPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, + { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, unpack_ul_cqi_information_value }, + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, srPduInstanceEnd, 0, 0) == 0) + return 0; + } + + return 1; + +} + +static int unpack_sr_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_sr_indication_t *pNfapiMsg = (nfapi_sr_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_SR_INDICATION_BODY_TAG, &pNfapiMsg->sr_indication_body, &unpack_sr_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} +static uint8_t unpack_cqi_indication_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_cqi_indication_rel8_t* cqi_pdu_rel8 = (nfapi_cqi_indication_rel8_t*)tlv; + + return (pull16(ppReadPackedMsg, &cqi_pdu_rel8->length, end) && + pull16(ppReadPackedMsg, &cqi_pdu_rel8->data_offset, end) && + pull8(ppReadPackedMsg, &cqi_pdu_rel8->ul_cqi, end) && + pull8(ppReadPackedMsg, &cqi_pdu_rel8->ri, end) && + pull16(ppReadPackedMsg, &cqi_pdu_rel8->timing_advance, end)); + +} + +static uint8_t unpack_cqi_indication_rel9_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_cqi_indication_rel9_t* cqi_pdu_rel9 = (nfapi_cqi_indication_rel9_t*)tlv; + + if(!(pull16(ppReadPackedMsg, &cqi_pdu_rel9->length, end) && + pull16(ppReadPackedMsg, &cqi_pdu_rel9->data_offset, end) && + pull8(ppReadPackedMsg, &cqi_pdu_rel9->ul_cqi, end) && + pull8(ppReadPackedMsg, &cqi_pdu_rel9->number_of_cc_reported, end))) + return 0; + + if(cqi_pdu_rel9->number_of_cc_reported > NFAPI_CC_MAX) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : out of bound array\n"); + return 0; + } + + if(!(pullarray8(ppReadPackedMsg, cqi_pdu_rel9->ri, NFAPI_CC_MAX, cqi_pdu_rel9->number_of_cc_reported, end) && + pull16(ppReadPackedMsg, &cqi_pdu_rel9->timing_advance, end) && + pull16(ppReadPackedMsg, &cqi_pdu_rel9->timing_advance_r9, end))) + return 0; + + return 1; +} + +static uint8_t unpack_cqi_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_cqi_indication_body_t* value = (nfapi_cqi_indication_body_t*)tlv; + + // the cqiBodyEnd points to the end of the cqi PDU's + uint8_t* cqiBodyEnd = *ppReadPackedMsg + value->tl.length; + + //uint8_t* cqiPduEnd = cqiBodyEnd; + //uint8_t* numberOfPdusAddress = *ppReadPackedMsg; + + if(cqiBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_cqis, end) == 0) + return 0; + + if(value->number_of_cqis > NFAPI_CQI_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of cqi ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_cqis, NFAPI_CQI_IND_MAX_PDU); + return -1; + } + + if(value->number_of_cqis > 0) + { + value->cqi_pdu_list = (nfapi_cqi_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_cqi_indication_pdu_t) * value->number_of_cqis, config); + if(value->cqi_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate cqi ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_cqis); + return 0; + } + } + else + { + value->cqi_pdu_list = 0; + } + + if(value->number_of_cqis > 0) + { + value->cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_cqi_indication_raw_pdu_t) * value->number_of_cqis, config); + if(value->cqi_raw_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate raw cqi ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_cqis); + return 0; + } + } + else + { + value->cqi_raw_pdu_list = 0; + } + + uint8_t i = 0; + for(i = 0; i < value->number_of_cqis; ++i) + { + nfapi_cqi_indication_pdu_t* pdu = &(value->cqi_pdu_list[i]); + memset(pdu, 0, sizeof(nfapi_cqi_indication_pdu_t)); + + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* cqiPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + + while((uint8_t*)(*ppReadPackedMsg) < cqiPduInstanceEnd) + { + nfapi_tl_t generic_tl; + if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + switch(generic_tl.tag) + { + case NFAPI_RX_UE_INFORMATION_TAG: + pdu->rx_ue_information.tl = generic_tl; + if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0) + return 0; + break; + case NFAPI_CQI_INDICATION_REL8_TAG: + pdu->cqi_indication_rel8.tl = generic_tl; + if(unpack_cqi_indication_rel8_value(&pdu->cqi_indication_rel8, ppReadPackedMsg, end) == 0) + return 0; + + break; + case NFAPI_CQI_INDICATION_REL9_TAG: + pdu->cqi_indication_rel9.tl = generic_tl; + if(unpack_cqi_indication_rel9_value(&pdu->cqi_indication_rel9, ppReadPackedMsg, end) == 0) + return 0; + + break; + case NFAPI_UL_CQI_INFORMATION_TAG: + pdu->ul_cqi_information.tl = generic_tl; + if(unpack_ul_cqi_information_value(&pdu->ul_cqi_information, ppReadPackedMsg, end) == 0) + return 0; + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_CQI.indication Invalid pdu type %d \n", generic_tl.tag ); + } + break; + + }; + } + } + + uint8_t idx = 0; + for(idx = 0; idx < value->number_of_cqis; ++idx) + { + if(value->cqi_pdu_list[idx].cqi_indication_rel8.tl.tag == NFAPI_CQI_INDICATION_REL8_TAG) + { + if(pullarray8(ppReadPackedMsg, &(value->cqi_raw_pdu_list[idx].pdu[0]), NFAPI_CQI_RAW_MAX_LEN, value->cqi_pdu_list[idx].cqi_indication_rel8.length, end) == 0) + return 0; + } + else if(value->cqi_pdu_list[idx].cqi_indication_rel9.tl.tag == NFAPI_CQI_INDICATION_REL9_TAG) + { + if(pullarray8(ppReadPackedMsg, &(value->cqi_raw_pdu_list[idx].pdu[0]), NFAPI_CQI_RAW_MAX_LEN, value->cqi_pdu_list[idx].cqi_indication_rel9.length, end) == 0) + return 0; + } + } + + + return 1; + +} + +static uint8_t unpack_cqi_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_cqi_indication_t *pNfapiMsg = (nfapi_cqi_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_CQI_INDICATION_BODY_TAG, &pNfapiMsg->cqi_indication_body, &unpack_cqi_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} +static uint8_t unpack_lbt_pdsch_req_pdu_rel13_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lbt_pdsch_req_pdu_rel13_t* value = (nfapi_lbt_pdsch_req_pdu_rel13_t*)tlv; + + return (pull32(ppReadPackedMsg, &value->handle, end) && + pull32(ppReadPackedMsg, &value->mp_cca, end) && + pull32(ppReadPackedMsg, &value->n_cca, end) && + pull32(ppReadPackedMsg, &value->offset, end) && + pull32(ppReadPackedMsg, &value->lte_txop_sf, end) && + pull16(ppReadPackedMsg, &value->txop_sfn_sf_end, end) && + pull32(ppReadPackedMsg, &value->lbt_mode, end)); +} + +static uint8_t unpack_lbt_drs_req_pdu_rel13_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lbt_drs_req_pdu_rel13_t* value = (nfapi_lbt_drs_req_pdu_rel13_t*)tlv; + + return (pull32(ppReadPackedMsg, &value->handle, end) && + pull32(ppReadPackedMsg, &value->offset, end) && + pull16(ppReadPackedMsg, &value->sfn_sf_end, end) && + pull32(ppReadPackedMsg, &value->lbt_mode, end)); +} + + +static uint8_t unpack_lbt_config_request_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_config_request_body_t* value = (nfapi_lbt_dl_config_request_body_t*)tlv; + + if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) + return 0; + + if(value->number_of_pdus > NFAPI_LBT_DL_CONFIG_REQ_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of lbt dl config pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_LBT_DL_CONFIG_REQ_MAX_PDU); + return 0; + } + + if(value->number_of_pdus) + { + value->lbt_dl_config_req_pdu_list = (nfapi_lbt_dl_config_request_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_lbt_dl_config_request_pdu_t) * value->number_of_pdus, config); + if(value->lbt_dl_config_req_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate lbt dl config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); + return 0; + } + } + else + { + value->lbt_dl_config_req_pdu_list = 0; + } + + + uint16_t i; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_lbt_dl_config_request_pdu_t* pdu = &(value->lbt_dl_config_req_pdu_list[i]); + + if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && + pull8(ppReadPackedMsg, &pdu->pdu_size, end))) + return 0; + + uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; + + if(packedPduEnd > end) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_LBT_DL_CONFIG_REQUEST_PDSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LBT_PDSCH_REQ_PDU_REL13_TAG, &pdu->lbt_pdsch_req_pdu.lbt_pdsch_req_pdu_rel13, &unpack_lbt_pdsch_req_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_LBT_DL_CONFIG_REQUEST_DRS_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LBT_DRS_REQ_PDU_REL13_TAG, &pdu->lbt_drs_req_pdu.lbt_drs_req_pdu_rel13, &unpack_lbt_drs_req_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL_CONFIG.request body invalid pdu type %d\n", pdu->pdu_type); + return 0; + } + } + + return 1; +} +static uint8_t unpack_lbt_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_config_request_t *pNfapiMsg = (nfapi_lbt_dl_config_request_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_LBT_DL_CONFIG_REQUEST_BODY_TAG, &pNfapiMsg->lbt_dl_config_request_body, &unpack_lbt_config_request_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_lbt_pdsch_rsp_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lbt_pdsch_rsp_pdu_rel13_t* value = (nfapi_lbt_pdsch_rsp_pdu_rel13_t*)tlv; + + return (pull32(ppReadPackedMsg, &value->handle, end) && + pull32(ppReadPackedMsg, &value->result, end) && + pull32(ppReadPackedMsg, &value->lte_txop_symbols, end) && + pull32(ppReadPackedMsg, &value->initial_partial_sf, end)); + +} +static uint8_t unpack_lbt_drs_rsp_pdu_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_lbt_drs_rsp_pdu_rel13_t* value = (nfapi_lbt_drs_rsp_pdu_rel13_t*)tlv; + + return (pull32(ppReadPackedMsg, &value->handle, end) && + pull32(ppReadPackedMsg, &value->result, end)); +} + +static uint8_t unpack_lbt_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_indication_body_t* value = (nfapi_lbt_dl_indication_body_t*)tlv; + + if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) + return 0; + + if(value->number_of_pdus > NFAPI_LBT_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of lbt dl ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_LBT_IND_MAX_PDU); + return 0; + } + + if(value->number_of_pdus > 0) + { + value->lbt_indication_pdu_list = (nfapi_lbt_dl_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_lbt_dl_indication_pdu_t) * value->number_of_pdus, config); + if(value->lbt_indication_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate lbt dl ind config pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); + return 0; + } + } + else + { + value->lbt_indication_pdu_list = 0; + } + + uint16_t i; + uint16_t total_number_of_pdus = value->number_of_pdus; + for(i = 0; i < total_number_of_pdus; ++i) + { + nfapi_lbt_dl_indication_pdu_t* pdu = &(value->lbt_indication_pdu_list[i]); + + if(!(pull8(ppReadPackedMsg, &pdu->pdu_type, end) && + pull8(ppReadPackedMsg, &pdu->pdu_size, end))) + return 0; + + uint8_t *packedPduEnd = (*ppReadPackedMsg) + pdu->pdu_size - 2; + + if(packedPduEnd > end) + return 0; + + switch(pdu->pdu_type) + { + case NFAPI_LBT_DL_RSP_PDSCH_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LBT_PDSCH_RSP_PDU_REL13_TAG, &pdu->lbt_pdsch_rsp_pdu.lbt_pdsch_rsp_pdu_rel13, &unpack_lbt_pdsch_rsp_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + case NFAPI_LBT_DL_RSP_DRS_PDU_TYPE: + { + unpack_tlv_t unpack_fns[] = + { + { NFAPI_LBT_DRS_RSP_PDU_REL13_TAG, &pdu->lbt_drs_rsp_pdu.lbt_drs_rsp_pdu_rel13, &unpack_lbt_drs_rsp_pdu_rel13_value}, + }; + + unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, packedPduEnd, 0, 0); + } + break; + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "LBT_DL.indication body invalid pdu type %d\n", pdu->pdu_type); + return 0; + } + } + + return 1; +} +static uint8_t unpack_lbt_dl_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_lbt_dl_indication_t *pNfapiMsg = (nfapi_lbt_dl_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_LBT_DL_INDICATION_BODY_TAG, &pNfapiMsg->lbt_dl_indication_body, &unpack_lbt_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_nb_harq_indication_fdd_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nb_harq_indication_fdd_rel13_t* value = (nfapi_nb_harq_indication_fdd_rel13_t*)tlv; + return (pull8(ppReadPackedMsg, &value->harq_tb1, end)); +} + + +static uint8_t unpack_nb_harq_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nb_harq_indication_body_t* value = (nfapi_nb_harq_indication_body_t*)tlv; + uint8_t* nbharqBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(nbharqBodyEnd > end) + return 0; + + if(pull16(ppReadPackedMsg, &value->number_of_harqs, end) == 0) + return 0; + + if(value->number_of_harqs > NFAPI_HARQ_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of harq ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_harqs, NFAPI_HARQ_IND_MAX_PDU); + return 0; + } + + value->nb_harq_pdu_list = (nfapi_nb_harq_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_nb_harq_indication_pdu_t) * value->number_of_harqs, config); + if(value->nb_harq_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_harqs); + return 0; + } + + uint8_t i = 0; + for(i = 0; i < value->number_of_harqs; ++i) + { + nfapi_nb_harq_indication_pdu_t* pdu = &(value->nb_harq_pdu_list[i]); + if(pull16(ppReadPackedMsg, &pdu->instance_length, end) == 0) + return 0; + + uint8_t* harqPduInstanceEnd = *ppReadPackedMsg + pdu->instance_length; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_RX_UE_INFORMATION_TAG, &pdu->rx_ue_information, unpack_rx_ue_information_value }, + { NFAPI_NB_HARQ_INDICATION_FDD_REL13_TAG, &pdu->nb_harq_indication_fdd_rel13, &unpack_nb_harq_indication_fdd_rel13_value}, + { NFAPI_UL_CQI_INFORMATION_TAG, &pdu->ul_cqi_information, &unpack_ul_cqi_information_value} + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, harqPduInstanceEnd, 0, 0) == 0) + return 0; + + } + + return 1; +} + +static uint8_t unpack_nb_harq_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_nb_harq_indication_t *pNfapiMsg = (nfapi_nb_harq_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_NB_HARQ_INDICATION_BODY_TAG, &pNfapiMsg->nb_harq_indication_body, &unpack_nb_harq_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_nrach_indication_rel13_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_nrach_indication_pdu_rel13_t* value = (nfapi_nrach_indication_pdu_rel13_t*)tlv; + + return (pull16(ppReadPackedMsg, &value->rnti, end) && + pull8(ppReadPackedMsg, &value->initial_sc, end) && + pull16(ppReadPackedMsg, &value->timing_advance, end) && + pull8(ppReadPackedMsg, &value->nrach_ce_level, end)); +} + static uint8_t unpack_ue_release_resp(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) { nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg; @@ -5837,218 +7377,275 @@ static uint8_t unpack_ue_release_resp(uint8_t **ppReadPackedMsg, uint8_t *end, v return 1; } -static uint8_t unpack_nrach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv; - uint8_t* nrachBodyEnd = *ppReadPackedMsg + value->tl.length; - - if(nrachBodyEnd > end) - return 0; - - if(pull8(ppReadPackedMsg, &value->number_of_initial_scs_detected, end) == 0) - return 0; - - if(value->number_of_initial_scs_detected > NFAPI_PREAMBLE_MAX_PDU) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of detected scs ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_initial_scs_detected, NFAPI_PREAMBLE_MAX_PDU); - return 0; - } - - value->nrach_pdu_list = (nfapi_nrach_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_nrach_indication_pdu_t) * value->number_of_initial_scs_detected, config); - if(value->nrach_pdu_list == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate nrach ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_initial_scs_detected); - return 0; - } - - uint8_t i = 0; - for(i = 0; i < value->number_of_initial_scs_detected; ++i) - { - nfapi_nrach_indication_pdu_t* pdu = &(value->nrach_pdu_list[i]); - - uint8_t* nrachPduInstanceEnd = *ppReadPackedMsg + 4 + 6; - - unpack_tlv_t unpack_fns[] = - { - { NFAPI_NRACH_INDICATION_REL13_TAG, &pdu->nrach_indication_rel13, &unpack_nrach_indication_rel13_value}, - }; - - if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, nrachPduInstanceEnd, 0, 0) == 0) - return 0; - - } - - return 1; -} - -static uint8_t unpack_nrach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_nrach_indication_t *pNfapiMsg = (nfapi_nrach_indication_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - { NFAPI_NRACH_INDICATION_BODY_TAG, &pNfapiMsg->nrach_indication_body, &unpack_nrach_indication_body_value}, - }; - - return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - }; - - return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) && - pulls32(ppReadPackedMsg, &pNfapiMsg->delta_sfn_sf, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_ul_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - }; - - return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) && - pull32(ppReadPackedMsg, &pNfapiMsg->t2, end) && - pull32(ppReadPackedMsg, &pNfapiMsg->t3, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - -static uint8_t unpack_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t*)msg; - - unpack_p7_tlv_t unpack_fns[] = - { - }; - - return (pull32(ppReadPackedMsg, &pNfapiMsg->last_sfn_sf, end) && - pull32(ppReadPackedMsg, &pNfapiMsg->time_since_last_timing_info, end) && - pull32(ppReadPackedMsg, &pNfapiMsg->dl_config_jitter, end) && - pull32(ppReadPackedMsg, &pNfapiMsg->tx_request_jitter, end) && - pull32(ppReadPackedMsg, &pNfapiMsg->ul_config_jitter, end) && - pull32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_jitter, end) && - pulls32(ppReadPackedMsg, &pNfapiMsg->dl_config_latest_delay, end) && - pulls32(ppReadPackedMsg, &pNfapiMsg->tx_request_latest_delay, end) && - pulls32(ppReadPackedMsg, &pNfapiMsg->ul_config_latest_delay, end) && - pulls32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_latest_delay, end) && - pulls32(ppReadPackedMsg, &pNfapiMsg->dl_config_earliest_arrival, end) && - pulls32(ppReadPackedMsg, &pNfapiMsg->tx_request_earliest_arrival, end) && - pulls32(ppReadPackedMsg, &pNfapiMsg->ul_config_earliest_arrival, end) && - pulls32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_earliest_arrival, end) && - unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); -} - - -// unpack length check - -static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) -{ - int retLen = 0; - - switch (msgId) - { - case NFAPI_DL_CONFIG_REQUEST: - if (unpackedBufLen >= sizeof(nfapi_dl_config_request_t)) - retLen = sizeof(nfapi_dl_config_request_t); - break; - - case NFAPI_UL_CONFIG_REQUEST: - if (unpackedBufLen >= sizeof(nfapi_ul_config_request_t)) - retLen = sizeof(nfapi_ul_config_request_t); - break; - - case NFAPI_SUBFRAME_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_subframe_indication_t)) - retLen = sizeof(nfapi_subframe_indication_t); - break; - - case NFAPI_HI_DCI0_REQUEST: - if (unpackedBufLen >= sizeof(nfapi_hi_dci0_request_t)) - retLen = sizeof(nfapi_hi_dci0_request_t); - break; - - case NFAPI_TX_REQUEST: - if (unpackedBufLen >= sizeof(nfapi_tx_request_t)) - retLen = sizeof(nfapi_tx_request_t); - break; - - case NFAPI_HARQ_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_harq_indication_t)) - retLen = sizeof(nfapi_harq_indication_t); - break; - - case NFAPI_CRC_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_crc_indication_t)) - retLen = sizeof(nfapi_crc_indication_t); - break; - - case NFAPI_RX_ULSCH_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_rx_indication_t)) - retLen = sizeof(nfapi_rx_indication_t); - break; - - case NFAPI_RACH_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_rach_indication_t)) - retLen = sizeof(nfapi_rach_indication_t); - break; - - case NFAPI_SRS_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_srs_indication_t)) - retLen = sizeof(nfapi_srs_indication_t); - break; - - case NFAPI_RX_SR_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_sr_indication_t)) - retLen = sizeof(nfapi_sr_indication_t); - break; - - case NFAPI_RX_CQI_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_cqi_indication_t)) - retLen = sizeof(nfapi_cqi_indication_t); - break; - - case NFAPI_LBT_DL_CONFIG_REQUEST: - if (unpackedBufLen >= sizeof(nfapi_lbt_dl_config_request_t)) - retLen = sizeof(nfapi_lbt_dl_config_request_t); - break; - - case NFAPI_LBT_DL_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_lbt_dl_indication_t)) - retLen = sizeof(nfapi_lbt_dl_indication_t); - break; - - case NFAPI_NB_HARQ_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_nb_harq_indication_t)) - retLen = sizeof(nfapi_nb_harq_indication_t); - break; - - case NFAPI_NRACH_INDICATION: - if (unpackedBufLen >= sizeof(nfapi_nrach_indication_t)) - retLen = sizeof(nfapi_nrach_indication_t); - break; - - case NFAPI_DL_NODE_SYNC: - if (unpackedBufLen >= sizeof(nfapi_dl_node_sync_t)) - retLen = sizeof(nfapi_dl_node_sync_t); - break; - - case NFAPI_UL_NODE_SYNC: - if (unpackedBufLen >= sizeof(nfapi_ul_node_sync_t)) - retLen = sizeof(nfapi_ul_node_sync_t); - break; - - case NFAPI_TIMING_INFO: - if (unpackedBufLen >= sizeof(nfapi_timing_info_t)) - retLen = sizeof(nfapi_timing_info_t); - break; +static uint8_t unpack_nrach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv; + uint8_t* nrachBodyEnd = *ppReadPackedMsg + value->tl.length; + + if(nrachBodyEnd > end) + return 0; + + if(pull8(ppReadPackedMsg, &value->number_of_initial_scs_detected, end) == 0) + return 0; + + if(value->number_of_initial_scs_detected > NFAPI_PREAMBLE_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of detected scs ind pdus exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_initial_scs_detected, NFAPI_PREAMBLE_MAX_PDU); + return 0; + } + + value->nrach_pdu_list = (nfapi_nrach_indication_pdu_t*)nfapi_p7_allocate(sizeof(nfapi_nrach_indication_pdu_t) * value->number_of_initial_scs_detected, config); + if(value->nrach_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate nrach ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_initial_scs_detected); + return 0; + } + + uint8_t i = 0; + for(i = 0; i < value->number_of_initial_scs_detected; ++i) + { + nfapi_nrach_indication_pdu_t* pdu = &(value->nrach_pdu_list[i]); + + uint8_t* nrachPduInstanceEnd = *ppReadPackedMsg + 4 + 6; + + unpack_tlv_t unpack_fns[] = + { + { NFAPI_NRACH_INDICATION_REL13_TAG, &pdu->nrach_indication_rel13, &unpack_nrach_indication_rel13_value}, + }; + + if(unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, nrachPduInstanceEnd, 0, 0) == 0) + return 0; + + } + + return 1; +} + +static uint8_t unpack_nrach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_nrach_indication_t *pNfapiMsg = (nfapi_nrach_indication_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + { NFAPI_NRACH_INDICATION_BODY_TAG, &pNfapiMsg->nrach_indication_body, &unpack_nrach_indication_body_value}, + }; + + return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_nr_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_dl_node_sync_t *pNfapiMsg = (nfapi_nr_dl_node_sync_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->delta_sfn_slot, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->delta_sfn_sf, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + + +static uint8_t unpack_nr_ul_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_ul_node_sync_t *pNfapiMsg = (nfapi_nr_ul_node_sync_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->t2, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->t3, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + + +static uint8_t unpack_ul_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->t2, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->t3, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + +static uint8_t unpack_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->last_sfn_sf, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->time_since_last_timing_info, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->dl_config_jitter, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->tx_request_jitter, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->ul_config_jitter, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_jitter, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->dl_config_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->tx_request_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->ul_config_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->dl_config_earliest_arrival, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->tx_request_earliest_arrival, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->ul_config_earliest_arrival, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->hi_dci0_earliest_arrival, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + + +static uint8_t unpack_nr_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_timing_info_t *pNfapiMsg = (nfapi_nr_timing_info_t*)msg; + + unpack_p7_tlv_t unpack_fns[] = + { + }; + + return (pull32(ppReadPackedMsg, &pNfapiMsg->last_sfn, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->last_slot, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->time_since_last_timing_info, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->dl_tti_jitter, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_jitter, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->ul_tti_jitter, end) && + pull32(ppReadPackedMsg, &pNfapiMsg->ul_dci_jitter, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->dl_tti_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->ul_tti_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->ul_dci_latest_delay, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->dl_tti_earliest_arrival, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_earliest_arrival, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->ul_tti_earliest_arrival, end) && + pulls32(ppReadPackedMsg, &pNfapiMsg->ul_dci_earliest_arrival, end) && + unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); +} + + + +// unpack length check + +static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) +{ + int retLen = 0; + + switch (msgId) + { + case NFAPI_DL_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_dl_config_request_t)) + retLen = sizeof(nfapi_dl_config_request_t); + break; + + case NFAPI_UL_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_ul_config_request_t)) + retLen = sizeof(nfapi_ul_config_request_t); + break; + + case NFAPI_SUBFRAME_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_subframe_indication_t)) + retLen = sizeof(nfapi_subframe_indication_t); + break; + + case NFAPI_HI_DCI0_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_hi_dci0_request_t)) + retLen = sizeof(nfapi_hi_dci0_request_t); + break; + + case NFAPI_TX_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_tx_request_t)) + retLen = sizeof(nfapi_tx_request_t); + break; + + case NFAPI_HARQ_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_harq_indication_t)) + retLen = sizeof(nfapi_harq_indication_t); + break; + + case NFAPI_CRC_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_crc_indication_t)) + retLen = sizeof(nfapi_crc_indication_t); + break; + + case NFAPI_RX_ULSCH_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_rx_indication_t)) + retLen = sizeof(nfapi_rx_indication_t); + break; + + case NFAPI_RACH_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_rach_indication_t)) + retLen = sizeof(nfapi_rach_indication_t); + break; + + case NFAPI_SRS_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_srs_indication_t)) + retLen = sizeof(nfapi_srs_indication_t); + break; + + case NFAPI_RX_SR_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_sr_indication_t)) + retLen = sizeof(nfapi_sr_indication_t); + break; + + case NFAPI_RX_CQI_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_cqi_indication_t)) + retLen = sizeof(nfapi_cqi_indication_t); + break; + + case NFAPI_LBT_DL_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_lbt_dl_config_request_t)) + retLen = sizeof(nfapi_lbt_dl_config_request_t); + break; + + case NFAPI_LBT_DL_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_lbt_dl_indication_t)) + retLen = sizeof(nfapi_lbt_dl_indication_t); + break; + + case NFAPI_NB_HARQ_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_nb_harq_indication_t)) + retLen = sizeof(nfapi_nb_harq_indication_t); + break; + + case NFAPI_NRACH_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_nrach_indication_t)) + retLen = sizeof(nfapi_nrach_indication_t); + break; + + case NFAPI_DL_NODE_SYNC: + if (unpackedBufLen >= sizeof(nfapi_dl_node_sync_t)) + retLen = sizeof(nfapi_dl_node_sync_t); + break; + + case NFAPI_UL_NODE_SYNC: + if (unpackedBufLen >= sizeof(nfapi_ul_node_sync_t)) + retLen = sizeof(nfapi_ul_node_sync_t); + break; + + case NFAPI_TIMING_INFO: + if (unpackedBufLen >= sizeof(nfapi_timing_info_t)) + retLen = sizeof(nfapi_timing_info_t); + break; case NFAPI_UE_RELEASE_REQUEST: if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t)) @@ -6060,125 +7657,251 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen retLen = sizeof(nfapi_ue_release_response_t); break; - default: - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId); - break; - } - - return retLen; -} - - -// Main unpack functions - public - -int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config) -{ - nfapi_p7_message_header_t *pMessageHeader = pUnpackedBuf; - uint8_t *pReadPackedMessage = pMessageBuf; - uint8_t *end = pMessageBuf + messageBufLen; - - if (pMessageBuf == NULL || pUnpackedBuf == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied pointers are null\n"); - return -1; - } - - if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); - return -1; - } - - // process the header - if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && - pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && - pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && - pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) && - pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) && - pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) - return -1; - - return 0; -} - -int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config) -{ - int result = 0; - nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t*)pUnpackedBuf; - uint8_t *pReadPackedMessage = pMessageBuf; - uint8_t *end = pMessageBuf + messageBufLen; - - if (pMessageBuf == NULL || pUnpackedBuf == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n"); - return -1; - } - - if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); - return -1; - } - - // clean the supplied buffer for - tag value blanking - (void)memset(pUnpackedBuf, 0, unpackedBufLen); - - // process the header - if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && - pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && - pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && - pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) && - pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) && - pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n"); - return -1; - } - - if((uint8_t*)(pMessageBuf + pMessageHeader->message_length) > end) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n"); - return -1; - } - - /* - if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n"); - return -1; - } - */ - - // look for the specific message - switch (pMessageHeader->message_id) - { - case NFAPI_DL_CONFIG_REQUEST: - if (check_unpack_length(NFAPI_DL_CONFIG_REQUEST, unpackedBufLen)) - result = unpack_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_UL_CONFIG_REQUEST: - if (check_unpack_length(NFAPI_UL_CONFIG_REQUEST, unpackedBufLen)) - result = unpack_ul_config_request(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_HI_DCI0_REQUEST: - if (check_unpack_length(NFAPI_HI_DCI0_REQUEST, unpackedBufLen)) - result = unpack_hi_dci0_request(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_TX_REQUEST: - if (check_unpack_length(NFAPI_TX_REQUEST, unpackedBufLen)) - result = unpack_tx_request(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId); + break; + } + + return retLen; +} + +static int check_nr_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen) +{ + int retLen = 0; + + switch (msgId) + { + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_nr_dl_tti_request_t)) + retLen = sizeof(nfapi_nr_dl_tti_request_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_nr_ul_tti_request_t)) + retLen = sizeof(nfapi_nr_ul_tti_request_t); + break; + + case NFAPI_SUBFRAME_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_subframe_indication_t)) + retLen = sizeof(nfapi_subframe_indication_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_nr_ul_dci_request_t)) + retLen = sizeof(nfapi_nr_ul_dci_request_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_nr_tx_data_request_t)) + retLen = sizeof(nfapi_nr_tx_data_request_t); + break; + + case NFAPI_HARQ_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_harq_indication_t)) + retLen = sizeof(nfapi_harq_indication_t); + break; + + case NFAPI_CRC_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_crc_indication_t)) + retLen = sizeof(nfapi_crc_indication_t); + break; + + case NFAPI_RX_ULSCH_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_rx_indication_t)) + retLen = sizeof(nfapi_rx_indication_t); + break; + + case NFAPI_RACH_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_rach_indication_t)) + retLen = sizeof(nfapi_rach_indication_t); + break; + + case NFAPI_SRS_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_srs_indication_t)) + retLen = sizeof(nfapi_srs_indication_t); + break; + + case NFAPI_RX_SR_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_sr_indication_t)) + retLen = sizeof(nfapi_sr_indication_t); + break; + + case NFAPI_RX_CQI_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_cqi_indication_t)) + retLen = sizeof(nfapi_cqi_indication_t); + break; + + case NFAPI_LBT_DL_CONFIG_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_lbt_dl_config_request_t)) + retLen = sizeof(nfapi_lbt_dl_config_request_t); + break; + + case NFAPI_LBT_DL_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_lbt_dl_indication_t)) + retLen = sizeof(nfapi_lbt_dl_indication_t); + break; + + case NFAPI_NB_HARQ_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_nb_harq_indication_t)) + retLen = sizeof(nfapi_nb_harq_indication_t); + break; + + case NFAPI_NRACH_INDICATION: + if (unpackedBufLen >= sizeof(nfapi_nrach_indication_t)) + retLen = sizeof(nfapi_nrach_indication_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC: + if (unpackedBufLen >= sizeof(nfapi_nr_dl_node_sync_t)) + retLen = sizeof(nfapi_nr_dl_node_sync_t); + break; + + case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC: + if (unpackedBufLen >= sizeof(nfapi_nr_ul_node_sync_t)) + retLen = sizeof(nfapi_nr_ul_node_sync_t); + break; + + case NFAPI_TIMING_INFO: + if (unpackedBufLen >= sizeof(nfapi_timing_info_t)) + retLen = sizeof(nfapi_timing_info_t); + break; + + case NFAPI_UE_RELEASE_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t)) + retLen = sizeof(nfapi_ue_release_request_t); + break; + + case NFAPI_UE_RELEASE_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t)) + retLen = sizeof(nfapi_ue_release_response_t); + break; + + default: + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId); + break; + } + + return retLen; +} + + + +// Main unpack functions - public + +int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config) +{ + nfapi_p7_message_header_t *pMessageHeader = pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + if (pMessageBuf == NULL || pUnpackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied pointers are null\n"); + return -1; + } + + if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + return -1; + } + + // process the header + if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && + pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) && + pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) && + pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) + return -1; + + return 0; +} + +int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config) +{ + int result = 0; + nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t*)pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + if (pMessageBuf == NULL || pUnpackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n"); + return -1; + } + + if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + return -1; + } + /* + uint8_t *ptr = pMessageBuf; + printf("\n Read P7 message unpack: "); + while(ptr < end){ + printf(" %d ", *ptr); + ptr++; + } + printf("\n"); +*/ + // clean the supplied buffer for - tag value blanking + (void)memset(pUnpackedBuf, 0, unpackedBufLen); + + // process the header + if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && + pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) && + pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) && + pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n"); + return -1; + } + + if((uint8_t*)(pMessageBuf + pMessageHeader->message_length) > end) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n"); + return -1; + } + + /* + if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n"); + return -1; + } + */ + + // look for the specific message + switch (pMessageHeader->message_id) + { + case NFAPI_DL_CONFIG_REQUEST: + if (check_unpack_length(NFAPI_DL_CONFIG_REQUEST, unpackedBufLen)) + result = unpack_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_UL_CONFIG_REQUEST: + if (check_unpack_length(NFAPI_UL_CONFIG_REQUEST, unpackedBufLen)) + result = unpack_ul_config_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + case NFAPI_TX_REQUEST: + if (check_unpack_length(NFAPI_TX_REQUEST, unpackedBufLen)) + result = unpack_tx_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + case NFAPI_HI_DCI0_REQUEST: + if (check_unpack_length(NFAPI_HI_DCI0_REQUEST, unpackedBufLen)) + result = unpack_hi_dci0_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; case NFAPI_UE_RELEASE_REQUEST: if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen)) @@ -6187,103 +7910,103 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn return -1; break; - case NFAPI_HARQ_INDICATION: - if (check_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen)) - result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_CRC_INDICATION: - if (check_unpack_length(NFAPI_CRC_INDICATION, unpackedBufLen)) - result = unpack_crc_indication(&pReadPackedMessage,end , pMessageHeader, config); - else - return -1; - break; - - case NFAPI_RX_ULSCH_INDICATION: - if (check_unpack_length(NFAPI_RX_ULSCH_INDICATION, unpackedBufLen)) - result = unpack_rx_indication(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_RACH_INDICATION: - if (check_unpack_length(NFAPI_RACH_INDICATION, unpackedBufLen)) - result = unpack_rach_indication(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_SRS_INDICATION: - if (check_unpack_length(NFAPI_SRS_INDICATION, unpackedBufLen)) - result = unpack_srs_indication(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_RX_SR_INDICATION: - if (check_unpack_length(NFAPI_RX_SR_INDICATION, unpackedBufLen)) - result = unpack_sr_indication(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_RX_CQI_INDICATION: - if (check_unpack_length(NFAPI_RX_CQI_INDICATION, unpackedBufLen)) - result = unpack_cqi_indication(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_LBT_DL_CONFIG_REQUEST: - if (check_unpack_length(NFAPI_LBT_DL_CONFIG_REQUEST, unpackedBufLen)) - result = unpack_lbt_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_LBT_DL_INDICATION: - if (check_unpack_length(NFAPI_LBT_DL_INDICATION, unpackedBufLen)) - result = unpack_lbt_dl_indication(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_NB_HARQ_INDICATION: - if (check_unpack_length(NFAPI_NB_HARQ_INDICATION, unpackedBufLen)) - result = unpack_nb_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_NRACH_INDICATION: - if (check_unpack_length(NFAPI_NRACH_INDICATION, unpackedBufLen)) - result = unpack_nrach_indication(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_DL_NODE_SYNC: - if (check_unpack_length(NFAPI_DL_NODE_SYNC, unpackedBufLen)) - result = unpack_dl_node_sync(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - - case NFAPI_UL_NODE_SYNC: - if (check_unpack_length(NFAPI_UL_NODE_SYNC, unpackedBufLen)) - result = unpack_ul_node_sync(&pReadPackedMessage, end , pMessageHeader, config); - else - return -1; - break; - - case NFAPI_TIMING_INFO: - if (check_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen)) - result = unpack_timing_info(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; + case NFAPI_HARQ_INDICATION: + if (check_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen)) + result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_CRC_INDICATION: + if (check_unpack_length(NFAPI_CRC_INDICATION, unpackedBufLen)) + result = unpack_crc_indication(&pReadPackedMessage,end , pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RX_ULSCH_INDICATION: + if (check_unpack_length(NFAPI_RX_ULSCH_INDICATION, unpackedBufLen)) + result = unpack_rx_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RACH_INDICATION: + if (check_unpack_length(NFAPI_RACH_INDICATION, unpackedBufLen)) + result = unpack_rach_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_SRS_INDICATION: + if (check_unpack_length(NFAPI_SRS_INDICATION, unpackedBufLen)) + result = unpack_srs_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RX_SR_INDICATION: + if (check_unpack_length(NFAPI_RX_SR_INDICATION, unpackedBufLen)) + result = unpack_sr_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RX_CQI_INDICATION: + if (check_unpack_length(NFAPI_RX_CQI_INDICATION, unpackedBufLen)) + result = unpack_cqi_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_LBT_DL_CONFIG_REQUEST: + if (check_unpack_length(NFAPI_LBT_DL_CONFIG_REQUEST, unpackedBufLen)) + result = unpack_lbt_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_LBT_DL_INDICATION: + if (check_unpack_length(NFAPI_LBT_DL_INDICATION, unpackedBufLen)) + result = unpack_lbt_dl_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_NB_HARQ_INDICATION: + if (check_unpack_length(NFAPI_NB_HARQ_INDICATION, unpackedBufLen)) + result = unpack_nb_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_NRACH_INDICATION: + if (check_unpack_length(NFAPI_NRACH_INDICATION, unpackedBufLen)) + result = unpack_nrach_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_DL_NODE_SYNC: + if (check_unpack_length(NFAPI_DL_NODE_SYNC, unpackedBufLen)) + result = unpack_dl_node_sync(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_UL_NODE_SYNC: + if (check_unpack_length(NFAPI_UL_NODE_SYNC, unpackedBufLen)) + result = unpack_ul_node_sync(&pReadPackedMessage, end , pMessageHeader, config); + else + return -1; + break; + + case NFAPI_TIMING_INFO: + if (check_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen)) + result = unpack_timing_info(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; case NFAPI_UE_RELEASE_RESPONSE: if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen)) @@ -6292,30 +8015,255 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn return -1; break; - default: - - if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && - pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) - { - if(config && config->unpack_p7_vendor_extension) - { - result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config); - } - else - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id); - } - } - else - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id); - } - break; - } - - if(result == 0) - return -1; - else - return 0; -} - + default: + + if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->unpack_p7_vendor_extension) + { + result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + break; + } + + if(result == 0) + return -1; + else + return 0; +} + +int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config) +{ + int result = 0; + nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t*)pUnpackedBuf; + uint8_t *pReadPackedMessage = pMessageBuf; + uint8_t *end = pMessageBuf + messageBufLen; + + if (pMessageBuf == NULL || pUnpackedBuf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n"); + return -1; + } + + if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen); + return -1; + } + /* + uint8_t *ptr = pMessageBuf; + printf("\n Read P7 message unpack: "); + while(ptr < end){ + printf(" %d ", *ptr); + ptr++; + } + printf("\n"); +*/ + // clean the supplied buffer for - tag value blanking + (void)memset(pUnpackedBuf, 0, unpackedBufLen); + + // process the header + if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) && + pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) && + pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) && + pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) && + pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n"); + return -1; + } + + if((uint8_t*)(pMessageBuf + pMessageHeader->message_length) > end) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n"); + return -1; + } + + /* + if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n"); + return -1; + } + */ + + // look for the specific message + switch (pMessageHeader->message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST, unpackedBufLen)) + result = unpack_dl_tti_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST, unpackedBufLen)) + result = unpack_ul_tti_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST, unpackedBufLen)) + result = unpack_tx_data_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST, unpackedBufLen)) + result = unpack_ul_dci_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_UE_RELEASE_REQUEST: + if (check_nr_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen)) + result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_HARQ_INDICATION: + if (check_nr_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen)) + result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_CRC_INDICATION: + if (check_nr_unpack_length(NFAPI_CRC_INDICATION, unpackedBufLen)) + result = unpack_crc_indication(&pReadPackedMessage,end , pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RX_ULSCH_INDICATION: + if (check_nr_unpack_length(NFAPI_RX_ULSCH_INDICATION, unpackedBufLen)) + result = unpack_rx_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RACH_INDICATION: + if (check_nr_unpack_length(NFAPI_RACH_INDICATION, unpackedBufLen)) + result = unpack_rach_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_SRS_INDICATION: + if (check_nr_unpack_length(NFAPI_SRS_INDICATION, unpackedBufLen)) + result = unpack_srs_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RX_SR_INDICATION: + if (check_nr_unpack_length(NFAPI_RX_SR_INDICATION, unpackedBufLen)) + result = unpack_sr_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_RX_CQI_INDICATION: + if (check_nr_unpack_length(NFAPI_RX_CQI_INDICATION, unpackedBufLen)) + result = unpack_cqi_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_LBT_DL_CONFIG_REQUEST: + if (check_nr_unpack_length(NFAPI_LBT_DL_CONFIG_REQUEST, unpackedBufLen)) + result = unpack_lbt_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_LBT_DL_INDICATION: + if (check_nr_unpack_length(NFAPI_LBT_DL_INDICATION, unpackedBufLen)) + result = unpack_lbt_dl_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_NB_HARQ_INDICATION: + if (check_nr_unpack_length(NFAPI_NB_HARQ_INDICATION, unpackedBufLen)) + result = unpack_nb_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_NRACH_INDICATION: + if (check_nr_unpack_length(NFAPI_NRACH_INDICATION, unpackedBufLen)) + result = unpack_nrach_indication(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC: + if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC, unpackedBufLen)) + result = unpack_nr_dl_node_sync(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC: + if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC, unpackedBufLen)) + result = unpack_nr_ul_node_sync(&pReadPackedMessage, end , pMessageHeader, config); + else + return -1; + break; + + case NFAPI_TIMING_INFO: + if (check_nr_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen)) + result = unpack_nr_timing_info(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + case NFAPI_UE_RELEASE_RESPONSE: + if (check_nr_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen)) + result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config); + else + return -1; + break; + + default: + + if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + if(config && config->unpack_p7_vendor_extension) + { + result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id); + } + break; + } + + if(result == 0) + return -1; + else + return 0; +} + + diff --git a/nfapi/open-nFAPI/pnf/inc/pnf.h b/nfapi/open-nFAPI/pnf/inc/pnf.h index ab38c66e09..8c4e5cf9ab 100644 --- a/nfapi/open-nFAPI/pnf/inc/pnf.h +++ b/nfapi/open-nFAPI/pnf/inc/pnf.h @@ -38,7 +38,9 @@ typedef struct { int pnf_connect(pnf_t *pnf); int pnf_message_pump(pnf_t *pnf); +int pnf_nr_message_pump(pnf_t *pnf); +int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len); int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len); int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len); int pnf_send_message(pnf_t* pnf, uint8_t* msg, uint32_t msg_len, uint16_t stream_id); diff --git a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h index 3f08d85e6b..1e2e2fa21d 100644 --- a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h +++ b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h @@ -29,15 +29,37 @@ typedef struct { uint16_t dl_conf_ontime; + uint16_t dl_tti_ontime; uint16_t dl_conf_late; + uint16_t dl_tti_late; uint16_t ul_conf_ontime; + uint16_t ul_tti_ontime; uint16_t ul_conf_late; + uint16_t ul_tti_late; uint16_t hi_dci0_ontime; uint16_t hi_dci0_late; + uint16_t ul_dci_ontime; + uint16_t ul_dci_late; uint16_t tx_ontime; uint16_t tx_late; + uint16_t tx_data_ontime; + uint16_t tx_data_late; } pnf_p7_stats_t; + +typedef struct { // TODO: replace with the stats + uint16_t dl_tti_ontime; + uint16_t dl_tti_late; + uint16_t ul_tti_ontime; + uint16_t ul_tti_late; + uint16_t ul_dci_ontime; + uint16_t ul_dci_late; + uint16_t tx_data_ontime; + uint16_t tx_data_late; +} pnf_p7_nr_stats_t; + + + typedef struct { uint8_t* buffer; uint16_t length; @@ -82,7 +104,7 @@ typedef struct { pthread_mutex_t pack_mutex; // should we allow the client to specifiy nfapi_pnf_p7_subframe_buffer_t subframe_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/]; - + nfapi_pnf_p7_slot_buffer_t slot_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/]; uint32_t sequence_number; uint16_t max_num_segments; @@ -94,6 +116,12 @@ typedef struct { uint16_t sfn_sf; uint32_t sf_start_time_hr; int32_t sfn_sf_shift; + + uint16_t sfn; + uint16_t slot; + uint16_t sfn_slot; + uint32_t slot_start_time_hr; + int32_t slot_shift; uint8_t timing_info_period_counter; uint8_t timing_info_aperiodic_send; // 0:false 1:true @@ -104,18 +132,26 @@ typedef struct { uint32_t ul_config_jitter; uint32_t hi_dci0_jitter; uint32_t tx_jitter; + + //P7 NR + uint32_t dl_tti_jitter; + uint32_t ul_tti_jitter; + uint32_t ul_dci_jitter; + uint32_t tx_data_jitter; uint32_t tick; pnf_p7_stats_t stats; + pnf_p7_nr_stats_t nr_stats; } pnf_p7_t; int pnf_p7_message_pump(pnf_p7_t* pnf_p7); - +int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7); int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len); int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len); +int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot); int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf); pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len); diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h index d169177d6b..fc9cd66077 100644 --- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h +++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h @@ -25,8 +25,14 @@ extern "C" { #include "nfapi_interface.h" #include "debug.h" #include +#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include +#include "openair1/PHY/defs_gNB.h" + + + /*! This enum is used to describe the states of the pnf */ @@ -121,6 +127,7 @@ typedef struct nfapi_pnf_config * The client is expected to send the PNF_PARAM.response after receiving the * PNF_PARAM.request. This can be done in the call back. */ + int (*pnf_nr_param_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_request_t* req); int (*pnf_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req); /*! A callback for the PNF_CONFIG.request @@ -133,7 +140,8 @@ typedef struct nfapi_pnf_config * PNF_CONFIG.request. This can be done in the call back. */ int (*pnf_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req); - + int (*pnf_nr_config_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_request_t* req); + /*! A callback for the PNF_START.request * \param config A pointer to the pnf configuration * \param req A data structure for the decoded PNF_CONFIG.request. This will have @@ -144,7 +152,8 @@ typedef struct nfapi_pnf_config * PNF_START.request. This can be done in the call back. */ int (*pnf_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req); - + int (*pnf_nr_start_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_request_t* req); + /*! A callback for the PNF_STOP.request * \param config A pointer to the pnf configuration * \param req A data structure for the decoded PNF_STOP.request. This will have @@ -167,7 +176,8 @@ typedef struct nfapi_pnf_config * PARAM.request. This can be done in the call back. */ int (*param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req); - + int (*nr_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_param_request_scf_t* req); + /*! A callback for the CONFIG.request * \param config A pointer to the pnf configuration * \param phy A pointer to the pnf phy configuration @@ -179,6 +189,7 @@ typedef struct nfapi_pnf_config * CONFIG.request. This can be done in the call back. */ int (*config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req); + int (*nr_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_config_request_scf_t* req); /*! A callback for the START.request * \param config A pointer to the pnf configuration @@ -190,8 +201,8 @@ typedef struct nfapi_pnf_config * The client is expected to send the START.response after the client has received the * first subframe indication from FAPI. */ - int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req); - + int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req); + int (*nr_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_start_request_scf_t* req); /*! A callback for the STOP.request * \param config A pointer to the pnf configuration * \param phy A pointer to the pnf phy configuration @@ -203,7 +214,8 @@ typedef struct nfapi_pnf_config * STOP.request. This can be done in the call back. */ int (*stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_stop_request_t* req); - + int (*nr_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_stop_request_t* req); + /*! A callback for the MEASUREMENT.request * \param config A pointer to the pnf configuration * \param phy A pointer to the pnf phy configuration @@ -355,6 +367,7 @@ int nfapi_pnf_config_destroy(nfapi_pnf_config_t* config); * \endcode */ int nfapi_pnf_start(nfapi_pnf_config_t* config); +int nfapi_nr_pnf_start(nfapi_pnf_config_t* config); /*! Stop the PNF library. * \param config A pointer to the pnf configuration @@ -371,6 +384,8 @@ int nfapi_pnf_stop(nfapi_pnf_config_t* config); * */ int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp); +int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_response_t* resp); + /*! Send the PNF_CONFIG.response * \param config A pointer to a pnf configuraiton @@ -379,6 +394,7 @@ int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_respons * */ int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp); +int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_response_t* resp); /*! Send the PNF_START.response * \param config A pointer to a pnf configuraiton @@ -387,7 +403,7 @@ int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_respo * */ int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp); - +int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_response_t* resp); /*! Send the PNF_STOP.response * \param config A pointer to a pnf configuraiton * \param resp A pointer to the message structure @@ -403,6 +419,7 @@ int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_ * */ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp); +int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_scf_t* resp); /*! Send the CONFIG.response * \param config A pointer to a pnf configuraiton @@ -411,7 +428,7 @@ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* res * */ int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp); - +int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_response_scf_t* resp); /*! Send the START.response * \param config A pointer to a pnf configuraiton * \param resp A pointer to the message structure @@ -419,6 +436,7 @@ int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* r * */ int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp); +int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_scf_t* resp); /*! Send the STOP.response * \param config A pointer to a pnf configuraiton @@ -550,6 +568,22 @@ typedef struct nfapi_ue_release_request_t* ue_release_req; } nfapi_pnf_p7_subframe_buffer_t; +typedef struct +{ + //uint16_t sfn_slot + int16_t sfn; + int16_t slot; + //TODO: Change P7 structs to NR + nfapi_nr_dl_tti_request_t* dl_tti_req;//nfapi_dl_config_request_t* dl_config_req; + nfapi_nr_ul_tti_request_t* ul_tti_req;//nfapi_ul_config_request_t* ul_config_req; + nfapi_nr_ul_dci_request_t* ul_dci_req;//nfapi_hi_dci0_request_t* hi_dci0_req; + nfapi_nr_tx_data_request_t* tx_data_req;//nfapi_tx_request_t* tx_req; + + //TODO: check these two later + //nfapi_lbt_dl_config_request_t* lbt_dl_config_req; + //nfapi_ue_release_request_t* ue_release_req; +} nfapi_pnf_p7_slot_buffer_t; + typedef struct nfapi_pnf_p7_config nfapi_pnf_p7_config_t; /*! The nfapi PNF PHY P7 configuration information created using the nfapi_pnf_p7_create function @@ -602,6 +636,8 @@ typedef struct nfapi_pnf_p7_config /*! The dummy subframe buffer structure that should be used in case there * are no 'valid' subframe messages */ nfapi_pnf_p7_subframe_buffer_t dummy_subframe; + + nfapi_pnf_p7_slot_buffer_t dummy_slot; // defining a slot equivalent for now /*! Configuration options for the p7 pack unpack functions*/ nfapi_p7_codec_config_t codec_config; @@ -611,6 +647,7 @@ typedef struct nfapi_pnf_p7_config // tdb : if these should be public uint16_t subframe_buffer_size; + uint16_t slot_buffer_size; uint8_t timing_info_mode_periodic; // 0:false 1:true uint8_t timing_info_mode_aperiodic; // 0:false 1:true uint8_t timing_info_period; // 1..225 in subframes @@ -620,6 +657,7 @@ typedef struct nfapi_pnf_p7_config * \param req A pointer to the dl config request message structure * \return not currently used */ + int (*dl_tti_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req); int (*dl_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req); /*! A callback for the UL_CONFIG.request @@ -627,6 +665,7 @@ typedef struct nfapi_pnf_p7_config * \param req A pointer to the ul config request message structure * \return not currently used */ + int (*ul_tti_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req); int (*ul_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req); /*! A callback for the HI_DCI0.request @@ -634,8 +673,9 @@ typedef struct nfapi_pnf_p7_config * \param req A pointer to the hi dci0 request message structure * \return not currently used */ + int (*ul_dci_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req); int (*hi_dci0_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req); - + /*! A callback for the TX_REQ.request * \param config A poiner to the PNF P7 config * \param req A pointer to the tx request message structure @@ -645,6 +685,7 @@ typedef struct nfapi_pnf_p7_config * will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0 * and then use the p7 codec config free function to release the pdu's when appropriate. */ + int (*tx_data_req_fn)(nfapi_pnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req); int (*tx_req)(nfapi_pnf_p7_config_t* config, nfapi_tx_request_t* req); /*! A callback for the LBT_DL_CONFIG.request @@ -708,6 +749,7 @@ int nfapi_pnf_p7_config_destroy(nfapi_pnf_p7_config_t* config); * This function will not return until nfapi_pnf_p7_stop is called. */ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config); +int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config); /*! Stop the PNF P7 library. * \param config A pointer to a PNF P7 config @@ -717,6 +759,21 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config); */ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config); +/*! NR Slot indication + * message copied from nfapi_pnf_p7_subframe_ind + * \param config A pointer to a PNF P7 config + * \param phy_id The phy_id for the phy instance + * \param sfn_sf The SFN and SF in the format of FAPI + * \return 0 means success, -1 means failure + * + * The client should call the subframe indication every 1ms. The PNF will + * respond by invoking the pnf p7 subframe callbacks with the messages from the subframe buffer + * + * If messages are not in the subframe buffer, they dummy subframe messages will be sent + */ +int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot); + + /*! Subframe indication * \param config A pointer to a PNF P7 config * \param phy_id The phy_id for the phy instance diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c index eec9ff80c3..fdafd93279 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf.c +++ b/nfapi/open-nFAPI/pnf/src/pnf.c @@ -26,9 +26,29 @@ #include #include #include - +#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include "pnf.h" +# if 1 // for hard-code (remove later) +#include "COMMON/platform_types.h" +#include "COMMON/platform_constants.h" +#include "common/ran_context.h" + +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + +#include "NR_BCCH-BCH-Message.h" +#include "NR_ServingCellConfigCommon.h" + +#include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include "SCHED_NR/phy_frame_config_nr.h" + +#include "NR_MIB.h" +#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h" + +#endif + #define MAX_SCTP_STREAMS 16 void nfapi_pnf_phy_config_delete_all(nfapi_pnf_config_t* config) @@ -63,6 +83,50 @@ nfapi_pnf_phy_config_t* nfapi_pnf_phy_config_find(nfapi_pnf_config_t* config, ui return 0; } +void pnf_nr_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_nr_pnf_param_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_PARAM.request received\n"); + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(nfapi_nr_pnf_param_request_t), &pnf->_public.codec_config) >= 0) + { + if(pnf->_public.state == NFAPI_PNF_IDLE) + { + if(pnf->_public.pnf_nr_param_req) + { + (pnf->_public.pnf_nr_param_req)(&pnf->_public, &req); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in IDLE state\n", __FUNCTION__); + + nfapi_nr_pnf_param_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_nr_pnf_pnf_param_resp(&pnf->_public, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + void pnf_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { // ensure it's valid @@ -173,6 +237,72 @@ void pnf_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } } +void pnf_nr_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + + + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_nr_pnf_config_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_CONFIG.request received\n"); + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0) + { + // ensure correct state + if(pnf->_public.state != NFAPI_PNF_RUNNING) + { + // delete the phy records + nfapi_pnf_phy_config_delete_all(&pnf->_public); + + // create the phy records + if (req.pnf_phy_rf_config.tl.tag == NFAPI_PNF_PHY_RF_TAG) + { + int i = 0; + for(i = 0; i < req.pnf_phy_rf_config.number_phy_rf_config_info; ++i) + { + nfapi_pnf_phy_config_t* phy = (nfapi_pnf_phy_config_t*)malloc(sizeof(nfapi_pnf_phy_config_t)); + memset(phy, 0, sizeof(nfapi_pnf_phy_config_t)); + + phy->state = NFAPI_PNF_PHY_IDLE; + phy->phy_id = req.pnf_phy_rf_config.phy_rf_config[i].phy_id; + + nfapi_pnf_phy_config_add(&(pnf->_public), phy); + } + } + + if(pnf->_public.pnf_nr_config_req) + { + (pnf->_public.pnf_nr_config_req)(&(pnf->_public), &req); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in correct state: %d\n", __FUNCTION__, pnf->_public.state); + + nfapi_nr_pnf_config_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_nr_pnf_pnf_config_resp(&(pnf->_public), &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + void pnf_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { // ensure it's valid @@ -215,6 +345,48 @@ void pnf_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } } +void pnf_nr_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_nr_pnf_start_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_START.request Received\n"); + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0) + { + if(pnf->_public.state == NFAPI_PNF_CONFIGURED) + { + if(pnf->_public.pnf_nr_start_req) + { + (pnf->_public.pnf_nr_start_req)(&(pnf->_public), &req); + } + } + else + { + nfapi_nr_pnf_start_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_PNF_START_RESPONSE; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_nr_pnf_pnf_start_resp(&(pnf->_public), &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + void pnf_handle_pnf_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { // ensure it's valid @@ -330,6 +502,78 @@ void pnf_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } } +void pnf_nr_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_nr_param_request_scf_t req; + + nfapi_pnf_config_t* config = &(pnf->_public); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PARAM.request received\n"); + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state == NFAPI_PNF_PHY_IDLE) + { + if(config->nr_param_req) + { + (config->nr_param_req)(config, phy, &req); + } + } + else + { + nfapi_nr_param_response_scf_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_nr_pnf_param_resp(config, &resp); + } + } + else + { + nfapi_nr_param_response_scf_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_nr_pnf_param_resp(config, &resp); + } + + } + else + { + nfapi_nr_param_response_scf_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_nr_pnf_param_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + + } +} + void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { @@ -401,6 +645,85 @@ void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } } + +void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_nr_config_request_scf_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "CONFIG.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + +#if 0 // emulate set_config TLV reception (hard-code) + int tdd_return = set_tdd_config_nr(&req, 1, 7, 6, 2, 4); +#endif + + if(phy) + { + if(phy->state != NFAPI_PNF_PHY_RUNNING) + { + if(config->nr_config_req) + { + (config->nr_config_req)(config, phy, &req); + + + } + } + else + { + nfapi_nr_config_response_scf_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CONFIG_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_nr_pnf_config_resp(config, &resp); + } + } + else + { + nfapi_nr_config_response_scf_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CONFIG_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_nr_pnf_config_resp(config, &resp); + } + } + else + { + nfapi_nr_config_response_scf_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_CONFIG_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_nr_pnf_config_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + } +} + void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { // ensure it's valid @@ -472,6 +795,77 @@ void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } } +void pnf_nr_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_nr_start_request_scf_t req; + + nfapi_pnf_config_t* config = &(pnf->_public); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() START.request received state:%d\n", __FUNCTION__, config->state); + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state != NFAPI_PNF_PHY_RUNNING) + { + if(config->nr_start_req) + { + (config->nr_start_req)(config, phy, &req); + } + } + else + { + nfapi_nr_start_response_scf_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_nr_pnf_start_resp(config, &resp); + } + } + else + { + nfapi_nr_start_response_scf_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_nr_pnf_start_resp(config, &resp); + } + } + else + { + nfapi_nr_start_response_scf_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_nr_pnf_start_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + + } +} + void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { // ensure it's valid @@ -543,6 +937,77 @@ void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } } +void pnf_nr_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + // ensure it's valid + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_nr_stop_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "STOP.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + { + if(config->state == NFAPI_PNF_RUNNING) + { + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id); + if(phy) + { + if(phy->state != NFAPI_PNF_PHY_RUNNING) + { + if(config->nr_stop_req) + { + (config->nr_stop_req)(config, phy, &req); + } + } + else + { + nfapi_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_stop_resp(config, &resp); + } + } + else + { + nfapi_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_stop_resp(config, &resp); + } + } + else + { + nfapi_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_stop_resp(config, &resp); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(req.vendor_extension) + pnf->_public.codec_config.deallocate(req.vendor_extension); + + } +} + void pnf_handle_measurement_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { // ensure it's valid @@ -1071,7 +1536,101 @@ void pnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_t* pnf, uin } } +void pnf_nr_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +{ + nfapi_p4_p5_message_header_t messageHeader; + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return; + } + + // unpack the message header + if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &pnf->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + switch (messageHeader.message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST: + pnf_nr_handle_pnf_param_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST: + pnf_nr_handle_pnf_config_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST: + pnf_nr_handle_pnf_start_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_PNF_STOP_REQUEST: + pnf_handle_pnf_stop_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST: + pnf_nr_handle_param_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST: + pnf_nr_handle_config_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST: + pnf_nr_handle_start_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST: + pnf_nr_handle_stop_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_MEASUREMENT_REQUEST: + pnf_handle_measurement_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_RSSI_REQUEST: + pnf_handle_rssi_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_CELL_SEARCH_REQUEST: + pnf_handle_cell_search_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_BROADCAST_DETECT_REQUEST: + pnf_handle_broadcast_detect_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST: + pnf_handle_system_information_schedule_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_SYSTEM_INFORMATION_REQUEST: + pnf_handle_system_information_request(pnf, pRecvMsg, recvMsgLen); + break; + + case NFAPI_NMM_STOP_REQUEST: + pnf_handle_nmm_stop_request(pnf, pRecvMsg, recvMsgLen); + break; + + default: + { + if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + pnf_handle_vendor_extension(pRecvMsg, recvMsgLen, pnf, messageHeader.message_id); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id); + } + } + break; + } +} void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { @@ -1169,6 +1728,24 @@ void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } } + +int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len) +{ + int packed_len = nfapi_nr_p5_message_pack(msg, msg_len, + pnf->tx_message_buffer, + sizeof(pnf->tx_message_buffer), + &pnf->_public.codec_config); + + if (packed_len < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed (%d)\n", packed_len); + return -1; + } + + return pnf_send_message(pnf, pnf->tx_message_buffer, packed_len, 0/*msg->stream_id*/); +} + + int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len) { int packed_len = nfapi_p5_message_pack(msg, msg_len, @@ -1393,8 +1970,15 @@ int pnf_connect(pnf_t* pnf) int pnf_send_message(pnf_t* pnf, uint8_t *msg, uint32_t len, uint16_t stream) { + if (pnf->sctp) { + printf("\nPNF SENDS: \n"); + for(int i=0; ip5_sock, msg, len, NULL, 0, 42/*config->sctp_stream_number*/, 0, stream/*P5_STREAM_ID*/, 0, 0) < 0) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "sctp_sendmsg failed errno: %d\n", errno); @@ -1412,7 +1996,6 @@ int pnf_send_message(pnf_t* pnf, uint8_t *msg, uint32_t len, uint16_t stream) return 0; } - int pnf_read_dispatch_message(pnf_t* pnf) { int socket_connected = 1; @@ -1486,6 +2069,13 @@ int pnf_read_dispatch_message(pnf_t* pnf) } else { + // print the received message + printf("\n MESSAGE RECEIVED: \n"); + for(int i=0; ip5_sock, header_buffer, header_buffer_size, /*(struct sockaddr*)&addr, &addr_len*/ 0, 0, &sndrcvinfo, &flags); + + if(message_size == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to peek sctp message size errno:%d\n", errno); + return 0; + } + + nfapi_p4_p5_message_header_t header; + int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0); + if(unpack_result < 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n"); + return 0; + } + message_size = header.message_length; + + // now have the size of the mesage + } + + if(message_size > stack_buffer_size) + { + dynamic_buffer = (uint8_t*)malloc(message_size); + + if(dynamic_buffer == NULL) + { + // todo : add error mesage + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size); + return -1; + } + + read_buffer = dynamic_buffer; + } + + { + int flags = 0; + (void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); + + int recvmsg_result = sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags); + if(recvmsg_result == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno); + } + else + { + // print the received message + printf("\n MESSAGE RECEIVED: \n"); + for(int i=0; ip5_sock, + inet_ntoa(addr.sin_addr), + ntohs(addr.sin_port), + sndrcvinfo.sinfo_assoc_id, + sndrcvinfo.sinfo_stream, + ntohl(sndrcvinfo.sinfo_ppid), + message_size, + flags); + */ + + // handle now if complete message in one or more segments + if ((flags & 0x80) == 0x80) + { + pnf_nr_handle_p5_message(pnf, read_buffer, message_size); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags); + + // assume socket disconnected + NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n"); + socket_connected = 0; + } + + + } + } + } + + if(dynamic_buffer) + { + free(dynamic_buffer); + } + + return socket_connected; + + } @@ -1597,3 +2316,64 @@ int pnf_message_pump(pnf_t* pnf) } +int pnf_nr_message_pump(pnf_t* pnf) +{ + uint8_t socketConnected = 1; + + while(socketConnected && pnf->terminate == 0) + { + fd_set rfds; + int selectRetval = 0; + + // select on a timeout and then get the message + FD_ZERO(&rfds); + FD_SET(pnf->p5_sock, &rfds); + + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + selectRetval = select(pnf->p5_sock+1, &rfds, NULL, NULL, &timeout); + + if(selectRetval == 0) + { + // timeout + continue; + } + else if (selectRetval == -1 && (errno == EINTR)) + { + // interrupted by signal + NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 Signal Interrupt %d\n", errno); + continue; + } + else if (selectRetval == -1) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 select() failed\n"); + sleep(1); + continue; + } + + if(FD_ISSET(pnf->p5_sock, &rfds)) + { + socketConnected = pnf_nr_read_dispatch_message(pnf); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Why are we here\n"); + } + } + + // Drop back to idle if we have lost connection + pnf->_public.state = NFAPI_PNF_PHY_IDLE; + + + // close the connection and socket + if (close(pnf->p5_sock) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "close(sctpSock) failed errno: %d\n", errno); + } + + return 0; + +} + diff --git a/nfapi/open-nFAPI/pnf/src/pnf_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_interface.c index dda0d0fdc6..8c9722c13e 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_interface.c @@ -19,6 +19,8 @@ #include #include #include +#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" nfapi_pnf_config_t* nfapi_pnf_config_create() { @@ -81,6 +83,40 @@ int nfapi_pnf_start(nfapi_pnf_config_t* config) return 0; } +int nfapi_nr_pnf_start(nfapi_pnf_config_t* config) +{ + // Verify that config is not null + if(config == 0) + return -1; + + // Make sure to set the defined trace function before using NFAPI_TRACE + if(config->trace) + nfapi_trace_g = config->trace; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + + pnf_t* _this = (pnf_t*)(config); + + while (_this->terminate == 0) + { + int connect_result = pnf_connect(_this); + + if(connect_result > 0) + { + pnf_nr_message_pump(_this); + } + else if(connect_result < 0) + { + return connect_result; + } + + sleep(1); + } + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() terminate=1 - EXITTING............\n", __FUNCTION__); + + return 0; +} + int nfapi_pnf_stop(nfapi_pnf_config_t* config) { // Verify that config is not null @@ -96,6 +132,21 @@ int nfapi_pnf_stop(nfapi_pnf_config_t* config) return 0; } + +int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_response_t* resp) +{ + // ensure it's valid + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_param_response_t)); +} + int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp) { // ensure it's valid @@ -129,6 +180,27 @@ int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_respo return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_config_response_t)); } + +int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_response_t* resp) +{ + // ensure it's valid + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + if(resp->error_code == NFAPI_MSG_OK) + { + config->state = NFAPI_PNF_CONFIGURED; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_config_response_t)); +} + + int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp) { // ensure it's valid @@ -148,6 +220,26 @@ int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_respons return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_start_response_t)); } +int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_response_t* resp) +{ + // ensure it's valid + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + if(resp->error_code == NFAPI_MSG_OK) + { + config->state = NFAPI_PNF_RUNNING; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_start_response_t)); +} + + int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_t* resp) { // ensure it's valid @@ -166,7 +258,6 @@ int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_ return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_stop_response_t)); } - int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp) { if (config == NULL || resp == NULL) @@ -180,6 +271,20 @@ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* res return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_param_response_t)); } + +int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_scf_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_param_response_scf_t)); +} + int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp) { if (config == NULL || resp == NULL) @@ -208,6 +313,35 @@ int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* r return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_config_response_t)); } +int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_response_scf_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id); + + if(phy) + { + if(resp->error_code == NFAPI_NR_CONFIG_MSG_OK) + { + phy->state = NFAPI_PNF_PHY_CONFIGURED; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id); + return -1; + } + + return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_config_response_scf_t)); +} + + int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp) { if (config == NULL || resp == NULL) @@ -235,6 +369,34 @@ int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* res return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_start_response_t)); } +int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_scf_t* resp) +{ + if (config == NULL || resp == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return -1; + } + + pnf_t* _this = (pnf_t*)(config); + + nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id); + if(phy) + { + if(resp->error_code == NFAPI_NR_START_MSG_OK) + { + phy->state = NFAPI_PNF_PHY_RUNNING; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknown phy id %d\n", __FUNCTION__, resp->header.phy_id); + return -1; + } + + return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_start_response_scf_t)); +} + + int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp) { if (config == NULL || resp == NULL) diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c index 5ba912e059..18891cdee9 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -32,8 +32,19 @@ #define FAPI2_IP_DSCP 0 extern uint16_t sf_ahead; +extern uint16_t slot_ahead; + //uint16_t sf_ahead=4; +void add_slot(uint16_t *frameP, uint16_t *slotP, int offset) +{ + uint16_t num_slots = 20; // set based on numerlogy (fixing for 1) + + *frameP = (*frameP + ((*slotP + offset) / num_slots))%1024; + + *slotP = ((*slotP + offset) % num_slots); +} + void add_sf(uint16_t *frameP, uint16_t *subframeP, int offset) { *frameP = (*frameP + ((*subframeP + offset) / 10))%1024; @@ -50,6 +61,22 @@ void subtract_sf(uint16_t *frameP, uint16_t *subframeP, int offset) *subframeP = (*subframeP+10-offset)%10; } +uint32_t sfnslot_add_slot(uint16_t sfn, uint16_t slot, int offset) +{ + uint32_t new_sfnslot; +// uint16_t sfn = NFAPI_SFNSLOT2SFN(sfnslot); +// uint16_t slot = NFAPI_SFNSLOT2SLOT(sfnslot); + + //printf("%s() sfn:%u sf:%u\n", __FUNCTION__, sfn, sf); + add_slot(&sfn, &slot, offset); + + new_sfnslot = sfn<<6|slot; + + //printf("%s() sfn:%u sf:%u offset:%d sfnsf:%d(DEC:%d) new:%d(DEC:%d)\n", __FUNCTION__, sfn, sf, offset, sfnsf, NFAPI_SFNSF2DEC(sfnsf), new_sfnsf, NFAPI_SFNSF2DEC(new_sfnsf)); + + return new_sfnslot; +} + uint16_t sfnsf_add_sf(uint16_t sfnsf, int offset) { uint16_t new_sfnsf; @@ -114,12 +141,34 @@ void pnf_p7_free(pnf_p7_t* pnf_p7, void* ptr) } // todo : for now these just malloc/free need to move to a memory cache +nfapi_nr_dl_tti_request_t* allocate_nfapi_dl_tti_request(pnf_p7_t* pnf_p7) +{ + void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_nr_dl_tti_request_t)); + //printf("%s() ptr:%p\n", __FUNCTION__, ptr); + return ptr; +} nfapi_dl_config_request_t* allocate_nfapi_dl_config_request(pnf_p7_t* pnf_p7) { void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_dl_config_request_t)); //printf("%s() ptr:%p\n", __FUNCTION__, ptr); return ptr; } +void deallocate_nfapi_dl_tti_request(nfapi_nr_dl_tti_request_t* req, pnf_p7_t* pnf_p7) +{ + //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->dl_config_request_body.dl_config_pdu_list); + /* + if(pnf_p7->_public.codec_config.deallocate) + { + //nfapi_nr_dl_tti_request_pdu_t *temp = &req->dl_tti_pdu_list; + (pnf_p7->_public.codec_config.deallocate)(req); + } + else + { + free(req); + } +*/ + pnf_p7_free(pnf_p7, req); +} void deallocate_nfapi_dl_config_request(nfapi_dl_config_request_t* req, pnf_p7_t* pnf_p7) { @@ -137,6 +186,13 @@ void deallocate_nfapi_dl_config_request(nfapi_dl_config_request_t* req, pnf_p7_t pnf_p7_free(pnf_p7, req); } +nfapi_nr_ul_tti_request_t* allocate_nfapi_ul_tti_request(pnf_p7_t* pnf_p7) +{ + void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_nr_ul_tti_request_t)); + //printf("%s() ptr:%p\n", __FUNCTION__, ptr); + return ptr; +} + nfapi_ul_config_request_t* allocate_nfapi_ul_config_request(pnf_p7_t* pnf_p7) { void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_ul_config_request_t)); @@ -144,6 +200,23 @@ nfapi_ul_config_request_t* allocate_nfapi_ul_config_request(pnf_p7_t* pnf_p7) return ptr; } +void deallocate_nfapi_ul_tti_request(nfapi_nr_ul_tti_request_t* req, pnf_p7_t* pnf_p7) +{ + //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->ul_config_request_body.ul_config_pdu_list); + /*if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(req->pdus_list); + (pnf_p7->_public.codec_config.deallocate)(req->groups_list); + } + else + { + free(req->pdus_list); + free(req->groups_list); + } + */ + pnf_p7_free(pnf_p7, req); +} + void deallocate_nfapi_ul_config_request(nfapi_ul_config_request_t* req, pnf_p7_t* pnf_p7) { //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->ul_config_request_body.ul_config_pdu_list); @@ -160,11 +233,31 @@ void deallocate_nfapi_ul_config_request(nfapi_ul_config_request_t* req, pnf_p7_t pnf_p7_free(pnf_p7, req); } +nfapi_nr_ul_dci_request_t* allocate_nfapi_ul_dci_request(pnf_p7_t* pnf_p7) +{ + return pnf_p7_malloc(pnf_p7, sizeof(nfapi_nr_ul_dci_request_t)); +} + nfapi_hi_dci0_request_t* allocate_nfapi_hi_dci0_request(pnf_p7_t* pnf_p7) { return pnf_p7_malloc(pnf_p7, sizeof(nfapi_hi_dci0_request_t)); } +void deallocate_nfapi_ul_dci_request(nfapi_nr_ul_dci_request_t* req, pnf_p7_t* pnf_p7) +{ + //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->hi_dci0_request_body.hi_dci0_pdu_list); + // if(pnf_p7->_public.codec_config.deallocate) + // { + // (pnf_p7->_public.codec_config.deallocate)(req->ul_dci_pdu_list); + // } + // else + // { + // free(req->ul_dci_pdu_list); + // } + + pnf_p7_free(pnf_p7, req); +} + void deallocate_nfapi_hi_dci0_request(nfapi_hi_dci0_request_t* req, pnf_p7_t* pnf_p7) { //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->hi_dci0_request_body.hi_dci0_pdu_list); @@ -181,11 +274,32 @@ void deallocate_nfapi_hi_dci0_request(nfapi_hi_dci0_request_t* req, pnf_p7_t* pn pnf_p7_free(pnf_p7, req); } +nfapi_nr_tx_data_request_t* allocate_nfapi_tx_data_request(pnf_p7_t* pnf_p7) +{ + return pnf_p7_malloc(pnf_p7, sizeof(nfapi_nr_tx_data_request_t)); +} + nfapi_tx_request_t* allocate_nfapi_tx_request(pnf_p7_t* pnf_p7) { return pnf_p7_malloc(pnf_p7, sizeof(nfapi_tx_request_t)); } +//TODO: Check if deallocate_nfapi_tx_data_request defn is proper +void deallocate_nfapi_tx_data_request(nfapi_nr_tx_data_request_t* req, pnf_p7_t* pnf_p7) +{ +/* + if(pnf_p7->_public.codec_config.deallocate) + { + (pnf_p7->_public.codec_config.deallocate)(req->pdu_list); + } + else + { + free(req->pdu_list); + } +*/ + pnf_p7_free(pnf_p7, req); +} + void deallocate_nfapi_tx_request(nfapi_tx_request_t* req, pnf_p7_t* pnf_p7) { int i = 0; @@ -385,11 +499,33 @@ void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reas } +static uint32_t get_slot_time(uint32_t now_hr, uint32_t slot_start_hr) +{ + if(now_hr < slot_start_hr) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr); + return 0; + } + else + { + uint32_t now_us = TIMEHR_USEC(now_hr); + uint32_t slot_start_us = TIMEHR_USEC(slot_start_hr); + + // if the us have wrapped adjust for it + if(now_hr < slot_start_us) + { + now_us += 500000; + } + + return now_us - slot_start_us; + } +} + static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) { if(now_hr < sf_start_hr) { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr); + NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe\n"); return 0; } else @@ -407,6 +543,8 @@ static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) } } + + int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t len) { // todo : consider how to do this only once @@ -414,7 +552,8 @@ int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t len) memset((char*)&remote_addr, 0, sizeof(struct sockaddr_in)); remote_addr.sin_family = AF_INET; remote_addr.sin_port = htons(pnf_p7->_public.remote_p7_port); - //remote_addr.sin_addr.s_addr = inet_addr(pnf_p7->_public.remote_p7_addr); + + if(inet_aton(pnf_p7->_public.remote_p7_addr, &remote_addr.sin_addr) == -1) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "inet_aton failed %d\n", errno); @@ -424,7 +563,9 @@ int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t len) socklen_t remote_addr_len = sizeof(struct sockaddr_in); int sendto_result; + if ((sendto_result = sendto((int)pnf_p7->p7_sock, (const char*)msg, len, 0, (const struct sockaddr*)&remote_addr, remote_addr_len)) < 0) +//if ((sendto_result = sendto((int)pnf_p7->p7_sock,"hello", 6, 0, (const struct sockaddr*)&remote_addr, remote_addr_len)) < 0) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s %s:%d sendto(%d, %p, %d) %d failed errno: %d\n", __FUNCTION__, pnf_p7->_public.remote_p7_addr, pnf_p7->_public.remote_p7_port, (int)pnf_p7->p7_sock, (const char*)msg, len, remote_addr_len, errno); return -1; @@ -527,6 +668,97 @@ int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* return 0; } + +int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* header, uint32_t msg_len) +{ + header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, pnf_p7->sequence_number); + + // Need to guard against different threads calling the encode function at the same time + if(pthread_mutex_lock(&(pnf_p7->pack_mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return -1; + } + + int len = nfapi_nr_p7_message_pack(header, pnf_p7->tx_message_buffer, sizeof(pnf_p7->tx_message_buffer), &pnf_p7->_public.codec_config); + + if (len < 0) + { + if(pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return -1; + } + + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p7_message_pack failed with return %d\n", len ); + return -1; + } + + if(len > pnf_p7->_public.segment_size) + { + int msg_body_len = len - NFAPI_P7_HEADER_LENGTH ; + int seg_body_len = pnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH ; + int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0); + + int segment = 0; + int offset = NFAPI_P7_HEADER_LENGTH; + uint8_t buffer[pnf_p7->_public.segment_size]; + for(segment = 0; segment < segment_count; ++segment) + { + uint8_t last = 0; + uint16_t size = pnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH; + if(segment + 1 == segment_count) + { + last = 1; + size = (msg_body_len) - (seg_body_len * segment); + } + + uint16_t segment_size = size + NFAPI_P7_HEADER_LENGTH; + + // Update the header with the m and segement + memcpy(&buffer[0], pnf_p7->tx_message_buffer, NFAPI_P7_HEADER_LENGTH); + + // set the segment length + buffer[4] = (segment_size & 0xFF00) >> 8; + buffer[5] = (segment_size & 0xFF); + + // set the m & segment number + buffer[6] = ((!last) << 7) + segment; + + memcpy(&buffer[NFAPI_P7_HEADER_LENGTH], pnf_p7->tx_message_buffer + offset, size); + offset += size; + + if(pnf_p7->_public.checksum_enabled) + { + nfapi_p7_update_checksum(buffer, segment_size); + } + + + pnf_p7_send_message(pnf_p7, &buffer[0], segment_size); + } + } + else + { + if(pnf_p7->_public.checksum_enabled) + { + nfapi_p7_update_checksum(pnf_p7->tx_message_buffer, len); + } + + // simple case that the message fits in a single segment + pnf_p7_send_message(pnf_p7, pnf_p7->tx_message_buffer, len); + } + + pnf_p7->sequence_number++; + + if(pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return -1; + } + + return 0; +} + void pnf_pack_and_send_timing_info(pnf_p7_t* pnf_p7) { nfapi_timing_info_t timing_info; @@ -558,6 +790,88 @@ void pnf_pack_and_send_timing_info(pnf_p7_t* pnf_p7) pnf_p7->timing_info_ms_counter = 0; } + +void pnf_nr_pack_and_send_timing_info(pnf_p7_t* pnf_p7) +{ + nfapi_nr_timing_info_t timing_info; + memset(&timing_info, 0, sizeof(timing_info)); + timing_info.header.message_id = NFAPI_TIMING_INFO; + timing_info.header.phy_id = pnf_p7->_public.phy_id; + + timing_info.last_sfn = pnf_p7->sfn; + timing_info.last_slot = pnf_p7->slot; + timing_info.time_since_last_timing_info = pnf_p7->timing_info_ms_counter; + + timing_info.dl_tti_jitter = pnf_p7->dl_tti_jitter; + timing_info.tx_data_request_jitter = pnf_p7->tx_data_jitter; + timing_info.ul_tti_jitter = pnf_p7->ul_tti_jitter; + timing_info.ul_dci_jitter = pnf_p7->ul_dci_jitter; + + timing_info.dl_tti_latest_delay = 0; + timing_info.tx_data_request_latest_delay = 0; + timing_info.ul_tti_latest_delay = 0; + timing_info.ul_dci_latest_delay = 0; + + timing_info.dl_tti_earliest_arrival = 0; + timing_info.tx_data_request_earliest_arrival = 0; + timing_info.ul_tti_earliest_arrival = 0; + timing_info.ul_dci_earliest_arrival = 0; + + + pnf_nr_p7_pack_and_send_p7_message(pnf_p7, &(timing_info.header), sizeof(timing_info)); + + pnf_p7->timing_info_ms_counter = 0; +} + + +void send_dummy_slot(pnf_p7_t* pnf_p7, uint16_t sfn, uint16_t slot) +{ + struct timespec t; + clock_gettime( CLOCK_MONOTONIC, &t); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(sfn_sf:%d) t:%ld.%09ld\n", __FUNCTION__, NFAPI_SFNSF2DEC(sfn_sf), t.tv_sec, t.tv_nsec); + + if(pnf_p7->_public.tx_data_req_fn && pnf_p7->_public.dummy_slot.tx_data_req) + { + pnf_p7->_public.dummy_slot.tx_data_req->SFN = sfn; + pnf_p7->_public.dummy_slot.tx_data_req->Slot = slot; + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy tx_req - enter\n"); + (pnf_p7->_public.tx_data_req_fn)(&pnf_p7->_public, pnf_p7->_public.dummy_slot.tx_data_req); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy tx_req - exit\n"); + } + if(pnf_p7->_public.dl_tti_req_fn && pnf_p7->_public.dummy_slot.dl_tti_req) + { + pnf_p7->_public.dummy_slot.dl_tti_req->SFN = sfn; + pnf_p7->_public.dummy_slot.dl_tti_req->Slot = slot; + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy dl_config_req - enter\n"); + (pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.dl_tti_req); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy dl_config_req - exit\n"); + } + if(pnf_p7->_public.ul_tti_req_fn && pnf_p7->_public.dummy_slot.ul_tti_req) + { + pnf_p7->_public.dummy_slot.ul_tti_req->SFN = sfn; + pnf_p7->_public.dummy_slot.ul_tti_req->Slot = slot; + NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy ul_config_req - enter\n"); + (pnf_p7->_public.ul_tti_req_fn)(NULL, &pnf_p7->_public, pnf_p7->_public.dummy_slot.ul_tti_req); + } + if(pnf_p7->_public.ul_dci_req_fn && pnf_p7->_public.dummy_slot.ul_dci_req) + { + pnf_p7->_public.dummy_slot.ul_dci_req->SFN = sfn; + pnf_p7->_public.dummy_slot.ul_dci_req->Slot = slot; + NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy hi_dci0 - enter\n"); + (pnf_p7->_public.ul_dci_req_fn)(NULL, &pnf_p7->_public, pnf_p7->_public.dummy_slot.ul_dci_req); + } + #if 0 + if(pnf_p7->_public.lbt_dl_config_req && pnf_p7->_public.dummy_subframe.lbt_dl_config_req) // TODO: Change later + { + pnf_p7->_public.dummy_slot.lbt_dl_config_req->sfn_sf = sfn; + NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy lbt - enter\n"); + (pnf_p7->_public.lbt_dl_config_req)(&pnf_p7->_public, pnf_p7->_public.dummy_slot.lbt_dl_config_req); + } + #endif +} + + void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf) { struct timespec t; @@ -599,6 +913,292 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf) } } + +int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t slot) +{ + // We could either send an event to the p7 thread have have it run the + // subframe or we could handle it here and lock access to the subframe + // buffers. If we do it on the p7 thread then we run the risk of blocking + // on the udp send. + // + // todo : start a timer to give us more of the 1 ms tick before send back + // the frame + + // todo : consider a more efficent lock mechasium + //uint16_t NUM_SLOTS = 20;//10* 2^mu + + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return -1; + } + + // save the curren time, sfn and slot + pnf_p7->slot_start_time_hr = pnf_get_current_time_hr(); + pnf_p7->sfn = sfn; + + pnf_p7->slot = slot; + + + + uint32_t sfn_slot_tx = sfnslot_add_slot(sfn, slot, slot_ahead); + uint16_t sfn_tx = sfn_slot_tx>>6; + uint16_t slot_tx = sfn_slot_tx & 0X3F; + + // uint32_t tx_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot); + uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot); + + + //uint32_t tx_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn_slot_tx); + + // If the subframe_buffer has been configured + if(pnf_p7->_public.slot_buffer_size!= 0) // for now value is same as sf_buffer_size + { + + // apply the shift to the incoming sfn_sf + if(pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync + { + uint16_t shifted_slot = slot + pnf_p7->slot_shift; + + // adjust for wrap-around + if(shifted_slot < 0) + shifted_slot += NFAPI_MAX_SFNSLOTDEC; + else if(shifted_slot > NFAPI_MAX_SFNSLOTDEC) + shifted_slot -= NFAPI_MAX_SFNSLOTDEC; + + // NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/slot (%d -> %d)\n", pnf_p7->sfn_slot_shift, NFAPI_SFNSF2DEC(sfn_slot), shifted_sfn_slot); + slot = shifted_slot; + + // + // DJP - why does the shift not apply to pnf_p7->sfn_sf??? + // + + pnf_p7->slot_shift = 0; + } + + uint32_t slot_dec = NFAPI_SFNSLOT2DEC(sfn, slot); + uint8_t buffer_index = slot_dec % pnf_p7->_public.slot_buffer_size; + + nfapi_pnf_p7_slot_buffer_t* slot_buffer = &(pnf_p7->slot_buffer[buffer_index]); + // see where the PNF_P7 slot buffer its getting filled + + uint8_t tx_buffer_index = tx_slot_dec % pnf_p7->_public.slot_buffer_size; + nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[tx_buffer_index]); + + if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d slot_buffer->sfn_sf:%d tx_slot_buffer->sfn_slot:%d sfn_sf:%d subframe_buffer[buffer_index:%u dl_config_req:%p tx_req:%p] " + "TX:sfn_sf:%d:tx_buffer_index:%d[dl_config_req:%p tx_req:%p]\n", + __FUNCTION__, + pnf_p7->slot_shift, + NFAPI_SFNSLOT2DEC(slot_buffer->sfn, slot_buffer->slot), + NFAPI_SFNSLOT2DEC(tx_slot_buffer->sfn, tx_slot_buffer->slot), + slot_dec, buffer_index, slot_buffer->dl_tti_req, slot_buffer->tx_data_req, + tx_slot_dec, tx_buffer_index, tx_slot_buffer->dl_tti_req, tx_slot_buffer->tx_data_req); + //TODO: Change later if required + + + // if the subframe buffer sfn sf is set then we have atlease 1 message + // from the vnf. + // todo : how to handle the messages we don't have, send dummies for + // now + + //printf("tx_subframe_buffer->sfn_sf:%d sfn_sf_tx:%d\n", tx_subframe_buffer->sfn_sf, sfn_sf_tx); + //printf("subframe_buffer->sfn_sf:%d sfn_sf:%d\n", subframe_buffer->sfn_sf, sfn_sf); + //printf("tx_slot_buff_sfn - %d, tx_slot_buf_slot - %d, sfn_tx = %d, sllot_tx - %d \n",tx_slot_buffer->sfn,tx_slot_buffer->slot,sfn_tx,slot_tx); + // if(tx_slot_buffer->slot == slot_tx && tx_slot_buffer->sfn == sfn_tx) + // { + + if(tx_slot_buffer->tx_data_req != 0) + { + + if(pnf_p7->_public.tx_data_req_fn) + { + (pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), tx_slot_buffer->tx_data_req); + } + } + else + { + // send dummy + if(pnf_p7->_public.tx_data_req_fn && pnf_p7->_public.dummy_slot.tx_data_req) + { + pnf_p7->_public.dummy_slot.tx_data_req->SFN = sfn_tx; + pnf_p7->_public.dummy_slot.tx_data_req->Slot = slot_tx; + + (pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), pnf_p7->_public.dummy_slot.tx_data_req); + } + } + //} + + if( tx_slot_buffer->dl_tti_req != 0) // ADDED & TO BYPASS ERROR + { + if(pnf_p7->_public.dl_tti_req_fn) + { + (pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), tx_slot_buffer->dl_tti_req); + } + } + + + else + { + // send dummy + if(pnf_p7->_public.dl_tti_req_fn && pnf_p7->_public.dummy_slot.dl_tti_req) + { + pnf_p7->_public.dummy_slot.dl_tti_req->SFN = sfn_tx; + pnf_p7->_public.dummy_slot.dl_tti_req->Slot = slot_tx; + (pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.dl_tti_req); + } + } + + if(tx_slot_buffer->ul_dci_req!= 0) + { + if(pnf_p7->_public.ul_dci_req_fn) + { + (pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), tx_slot_buffer->ul_dci_req); + } + } + else + { + //send dummy + if(pnf_p7->_public.ul_dci_req_fn && pnf_p7->_public.dummy_slot.ul_dci_req) + { + pnf_p7->_public.dummy_slot.ul_dci_req->SFN = sfn_tx; + pnf_p7->_public.dummy_slot.ul_dci_req->Slot = slot_tx; + (pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_dci_req); + } + } + if(tx_slot_buffer->dl_tti_req != 0) + { + deallocate_nfapi_dl_tti_request(tx_slot_buffer->dl_tti_req, pnf_p7); + tx_slot_buffer->dl_tti_req = 0; + } + + if(tx_slot_buffer->tx_data_req != 0) + { + deallocate_nfapi_tx_data_request(tx_slot_buffer->tx_data_req, pnf_p7); + tx_slot_buffer->tx_data_req = 0; + } + + if(tx_slot_buffer->ul_dci_req != 0) + { + deallocate_nfapi_ul_dci_request(tx_slot_buffer->ul_dci_req, pnf_p7); + tx_slot_buffer->ul_dci_req = 0; + } + else + { + // If we ever need to "send" a dummy ul_config this won't work!!! + // send_dummy_subframe(pnf_p7, sfn_sf_tx); + + // send_dummy_slot(pnf_p7, sfn_tx, slot_tx); + } + + + + if(slot_buffer->sfn == sfn && slot_buffer->slot == slot ) + { + + if(slot_buffer->ul_tti_req != 0) + { + if(pnf_p7->_public.ul_tti_req_fn) + { + (pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), slot_buffer->ul_tti_req); + } + //deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7); + } + else + { + // send dummy + if(pnf_p7->_public.ul_tti_req_fn && pnf_p7->_public.dummy_slot.ul_tti_req) + { + pnf_p7->_public.dummy_slot.ul_tti_req->SFN = sfn; + pnf_p7->_public.dummy_slot.ul_tti_req->Slot = slot; + (pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_tti_req); + } + } + //if(subframe_buffer->dl_config_req != 0) + //deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7); + //if(subframe_buffer->tx_req != 0) + //deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7); + if(slot_buffer->ul_tti_req != 0) + { + deallocate_nfapi_ul_tti_request(slot_buffer->ul_tti_req, pnf_p7); + slot_buffer->ul_tti_req = 0; + + } + #if 0 + if(slot_buffer->lbt_dl_config_req != 0) + { + deallocate_nfapi_lbt_dl_config_request(slot_buffer->lbt_dl_config_req, pnf_p7); + slot_buffer->lbt_dl_config_req = 0; + } + #endif + } // sfn_slot match + + + if ( slot_buffer->dl_tti_req == 0 && + slot_buffer->tx_data_req == 0 && + slot_buffer->ul_tti_req == 0) + //slot_buffer->lbt_dl_config_req == 0 && + //slot_buffer->ue_release_req == 0) + { + memset(&(pnf_p7->slot_buffer[buffer_index]), 0, sizeof(nfapi_pnf_p7_slot_buffer_t)); + pnf_p7->slot_buffer[buffer_index].sfn = -1; + pnf_p7->slot_buffer[buffer_index].slot = -1; + } + + //printf("pnf_p7->_public.timing_info_mode_periodic:%d pnf_p7->timing_info_period_counter:%d pnf_p7->_public.timing_info_period:%d\n", pnf_p7->_public.timing_info_mode_periodic, pnf_p7->timing_info_period_counter, pnf_p7->_public.timing_info_period); + //printf("pnf_p7->_public.timing_info_mode_aperiodic:%d pnf_p7->timing_info_aperiodic_send:%d\n", pnf_p7->_public.timing_info_mode_aperiodic, pnf_p7->timing_info_aperiodic_send); + //printf("pnf_p7->timing_info_ms_counter:%d\n", pnf_p7->timing_info_ms_counter); + + // send the periodic timing info if configured + if(pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period) + { + pnf_nr_pack_and_send_timing_info(pnf_p7); + + pnf_p7->timing_info_period_counter = 0; + } + else if(pnf_p7->_public.timing_info_mode_aperiodic && pnf_p7->timing_info_aperiodic_send) + { + pnf_nr_pack_and_send_timing_info(pnf_p7); + + pnf_p7->timing_info_aperiodic_send = 0; + } + else + { + pnf_p7->timing_info_ms_counter++; + } + + } + else + { + //send_dummy_subframe(pnf_p7, sfn_sf_tx); + } + + + //printf("pnf_p7->tick:%d\n", pnf_p7->tick); + // if(pnf_p7->tick == 1000) // why? + // { + // // TODO: change stats to nr_stats + // NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF P7:%d] (ONTIME/LATE) DL:(%d/%d) UL:(%d/%d) HI:(%d/%d) TX:(%d/%d)\n", pnf_p7->_public.phy_id, + // pnf_p7->stats.dl_conf_ontime, pnf_p7->stats.dl_conf_late, + // pnf_p7->stats.ul_conf_ontime, pnf_p7->stats.ul_conf_late, + // pnf_p7->stats.hi_dci0_ontime, pnf_p7->stats.hi_dci0_late, + // pnf_p7->stats.tx_ontime, pnf_p7->stats.tx_late); + // pnf_p7->tick = 0; + // memset(&pnf_p7->stats, 0, sizeof(pnf_p7->stats)); + // } + // pnf_p7->tick++; + + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return -1; + } + + return 0; +} + + + int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) { // We could either send an event to the p7 thread have have it run the @@ -621,8 +1221,8 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) pnf_p7->sf_start_time_hr = pnf_get_current_time_hr(); pnf_p7->sfn_sf = sfn_sf; - uint32_t sfn_sf_tx = sfnsf_add_sf(sfn_sf, sf_ahead); - uint32_t tx_sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf_tx); + uint32_t sfn_sf_tx = sfnsf_add_sf(sfn_sf, sf_ahead); + uint32_t tx_sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf_tx); // If the subframe_buffer has been configured if(pnf_p7->_public.subframe_buffer_size != 0) @@ -890,6 +1490,82 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) // return 1 if in window // return 0 if out of window + +uint8_t is_nr_p7_request_in_window(uint16_t sfn,uint16_t slot, const char* name, pnf_p7_t* phy) +{ + uint32_t recv_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot); + uint32_t current_sfn_slot_dec = NFAPI_SFNSLOT2DEC(phy->sfn,phy->slot); + printf("p7_msg_sfn: %d, p7_msg_slot: %d, phy_sfn:%d , phy_slot:%d \n",sfn,slot,phy->sfn,phy->slot); + uint8_t in_window = 0; + uint8_t timing_window = phy->_public.slot_buffer_size; + + // if(recv_sfn_slot_dec <= current_sfn_slot_dec) + // { + // // Need to check for wrap in window + // if(((recv_sfn_slot_dec + timing_window) % NFAPI_MAX_SFNSLOTDEC) < recv_sfn_slot_dec) + // { + // if(current_sfn_slot_dec > ((recv_sfn_slot_dec + timing_window) % NFAPI_MAX_SFNSLOTDEC)) + // { + // // out of window + // NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is late %d (with wrap)\n", current_sfn_slot_dec, name, recv_sfn_slot_dec); + // } + // else + // { + // // ok + // //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d (with wrap)\n", current_sfn_sf_dec, name, recv_sfn_sf_dec); + // in_window = 1; + // } + // } + // else + // { + // if((current_sfn_slot_dec - recv_sfn_slot_dec) <= timing_window) + // { + // // in window + // //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec); + // in_window = 1; + // } + // //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in late %d (delta:%d)\n", current_sfn_slot_dec, name, recv_sfn_slot_dec, (current_sfn_slot_dec - recv_sfn_slot_dec)); + // } + + // } + // else + // { + // // Need to check it is in window + // if((recv_sfn_slot_dec - current_sfn_slot_dec) <= timing_window) + // { + // // in window + // //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_sf_dec, name, recv_sfn_sf_dec); + // in_window = 1; + // } + // else + // { + // // too far in the future + // NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is out of window %d (delta:%d) [max:%d]\n", current_sfn_slot_dec, name, recv_sfn_slot_dec, (recv_sfn_slot_dec - current_sfn_slot_dec), timing_window); + // } + + // } + if(current_sfn_slot_dec <= recv_sfn_slot_dec + timing_window){ + in_window = 1; + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec); + } + else if(current_sfn_slot_dec + NFAPI_MAX_SFNSLOTDEC <= recv_sfn_slot_dec + timing_window){ //checking for wrap + in_window = 1; + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec); + } + + else + { + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is out of window %d (delta:%d) [max:%d]\n", current_sfn_slot_dec, name, recv_sfn_slot_dec, (current_sfn_slot_dec - recv_sfn_slot_dec), timing_window); + + }//Need to add more cases + + + return in_window; +} + + + uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy) { uint32_t recv_sfn_sf_dec = NFAPI_SFNSF2DEC(sfnsf); @@ -943,8 +1619,97 @@ uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy) } -// P7 messages -// +// P7 messages +void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req Received\n"); + nfapi_nr_dl_tti_request_t* req = allocate_nfapi_dl_tti_request(pnf_p7); + + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_dl_tti_request structure\n"); + return; + } + + int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_dl_tti_request_t), &(pnf_p7->_public.codec_config)); + + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } +#if 0 + if ( + 0 && + (NFAPI_SFNSF2DEC(req->sfn_sf) % 100 ==0 || + NFAPI_SFNSF2DEC(req->sfn_sf) % 105 ==0 + ) + ) + NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req sfn_sf:%d pdcch:%u dci:%u pdu:%u pdsch_rnti:%u pcfich:%u\n", + NFAPI_SFNSF2DEC(req->sfn_sf), + req->dl_config_request_body.number_pdcch_ofdm_symbols, + req->dl_config_request_body.number_dci, + req->dl_config_request_body.number_pdu, + req->dl_config_request_body.number_pdsch_rnti, + req->dl_config_request_body.transmission_power_pcfich + ); +#endif + + if(is_nr_p7_request_in_window(req->SFN,req->Slot, "dl_tti_request", pnf_p7)) + { + uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot); + uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size; + + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + //NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_TTI_REQ sfn_slot:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index); + + // if there is already an dl_config_req make sure we free it. + if(pnf_p7->slot_buffer[buffer_index].dl_tti_req != 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "%s() is_nr_p7_request_in_window()=TRUE buffer_index occupied - free it first sfn_slot:%d buffer_index:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(req->SFN,req->Slot), buffer_index); + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing dl_config_req at index %d (%d/%d)", + // pMyPhyInfo->sfnSf, bufferIdx, + // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); + deallocate_nfapi_dl_tti_request(pnf_p7->slot_buffer[buffer_index].dl_tti_req, pnf_p7); + } + + // saving dl_config_request in subframe buffer + pnf_p7->slot_buffer[buffer_index].sfn = req->SFN; + pnf_p7->slot_buffer[buffer_index].slot = req->Slot; + pnf_p7->slot_buffer[buffer_index].dl_tti_req = req; + + pnf_p7->stats.dl_tti_ontime++; + } + else + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "NOT storing dl_config_req SFN/SF %d\n", req->sfn_sf); + deallocate_nfapi_dl_tti_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.dl_tti_late++; + } + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack dl_tti_req"); + deallocate_nfapi_dl_tti_request(req, pnf_p7); + } +} + + void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req Received\n"); @@ -1035,6 +1800,80 @@ void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ } } + +void pnf_handle_ul_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "UL_CONFIG.req Received\n"); + + nfapi_nr_ul_tti_request_t* req = allocate_nfapi_ul_tti_request(pnf_p7); + + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_ul_tti_request structure\n"); + return; + } + + int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_ul_tti_request_t), &(pnf_p7->_public.codec_config)); + + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } + + if(is_nr_p7_request_in_window(req->SFN,req->Slot, "ul_tti_request", pnf_p7)) + { + uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot); + uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size; + + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UL_TTI_REQ sfn_slot:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index); + + if(pnf_p7->slot_buffer[buffer_index].ul_tti_req != 0) + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing ul_config_req at index %d (%d/%d)", + // pMyPhyInfo->sfnSf, bufferIdx, + // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); + + deallocate_nfapi_ul_tti_request(pnf_p7->slot_buffer[buffer_index].ul_tti_req, pnf_p7); + } + + pnf_p7->slot_buffer[buffer_index].sfn = req->SFN; + pnf_p7->slot_buffer[buffer_index].slot = req->Slot; + pnf_p7->slot_buffer[buffer_index].ul_tti_req = req; + + pnf_p7->stats.ul_tti_ontime++; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] NOT storing ul_tti_req OUTSIDE OF TRANSMIT BUFFER WINDOW SFN/SLOT %d\n", NFAPI_SFNSLOT2DEC(pnf_p7->sfn,pnf_p7->slot), NFAPI_SFNSLOT2DEC(req->SFN,req->Slot)); + deallocate_nfapi_ul_tti_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.ul_tti_late++; + } + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack ul_tti_req\n"); + deallocate_nfapi_ul_tti_request(req, pnf_p7); + } +} + void pnf_handle_ul_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "UL_CONFIG.req Received\n"); @@ -1107,7 +1946,79 @@ void pnf_handle_ul_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ } } + +void pnf_handle_ul_dci_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "HI_DCI0.req Received\n"); + + nfapi_nr_ul_dci_request_t* req = allocate_nfapi_ul_dci_request(pnf_p7); + + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate nfapi_ul_dci_request structure\n"); + return; + } + + int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_ul_dci_request_t), &pnf_p7->_public.codec_config); + + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } + + if(is_nr_p7_request_in_window(req->SFN,req->Slot,"ul_dci_request", pnf_p7)) + { + uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot); + uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size; + + if(pnf_p7->slot_buffer[buffer_index].ul_dci_req!= 0) + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing hi_dci0_req at index %d (%d/%d)", + // pMyPhyInfo->sfnSf, bufferIdx, + // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); + + deallocate_nfapi_ul_dci_request(pnf_p7->slot_buffer[buffer_index].ul_dci_req, pnf_p7); + } + + pnf_p7->slot_buffer[buffer_index].sfn = req->SFN; + pnf_p7->slot_buffer[buffer_index].ul_dci_req = req; + + pnf_p7->stats.ul_dci_ontime++; + + } + else + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] NOT storing hi_dci0_req SFN/SF %d/%d\n", pMyPhyInfo->sfnSf, SFNSF2SFN(req->sfn_sf), SFNSF2SF(req->sfn_sf)); + deallocate_nfapi_ul_dci_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.ul_dci_late++; + } + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack hi_dci0_req\n"); + deallocate_nfapi_ul_dci_request(req, pnf_p7); + } +} + + + void pnf_handle_hi_dci0_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) + { //NFAPI_TRACE(NFAPI_TRACE_INFO, "HI_DCI0.req Received\n"); @@ -1175,6 +2086,87 @@ void pnf_handle_hi_dci0_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7 } } + +void pnf_handle_tx_data_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +{ + //NFAPI_TRACE(NFAPI_TRACE_INFO, "TX.req Received\n"); + + nfapi_nr_tx_data_request_t* req = allocate_nfapi_tx_data_request(pnf_p7); + + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_tx_request structure\n"); + return; + } + + int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_tx_data_request_t), &pnf_p7->_public.codec_config); + if(unpack_result == 0) + { + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } + + if(is_nr_p7_request_in_window(req->SFN, req->Slot,"tx_request", pnf_p7)) + { + uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot); + uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size; + + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE TX_DATA_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index); +#if 0 + if (0 && NFAPI_SFNSF2DEC(req->sfn_sf)%100==0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX_REQ.req sfn_sf:%d pdus:%d - TX_REQ is within window\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(req->sfn_sf), + req->tx_request_body.number_of_pdus); +#endif + + if(pnf_p7->slot_buffer[buffer_index].tx_data_req != 0) + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing tx_req at index %d (%d/%d)", + // pMyPhyInfo->sfnSf, bufferIdx, + // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf)); + + deallocate_nfapi_tx_data_request(pnf_p7->slot_buffer[buffer_index].tx_data_req, pnf_p7); + } + + pnf_p7->slot_buffer[buffer_index].sfn = req->SFN; + pnf_p7->slot_buffer[buffer_index].slot = req->Slot; + pnf_p7->slot_buffer[buffer_index].tx_data_req = req; + + pnf_p7->stats.tx_data_ontime++; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() TX_DATA_REQUEST Request is outside of window REQ:SFN_SLOT:%d CURR:SFN_SLOT:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(req->SFN,req->Slot), NFAPI_SFNSLOT2DEC(pnf_p7->sfn,pnf_p7->slot)); + + deallocate_nfapi_tx_data_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.tx_data_late++; + } + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + } + else + { + deallocate_nfapi_tx_data_request(req, pnf_p7); + } +} + + + void pnf_handle_tx_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "TX.req Received\n"); @@ -1437,6 +2429,29 @@ uint32_t calculate_t2(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_t return t2; } +uint32_t calculate_nr_t2(uint32_t now_time_hr, uint16_t sfn,uint16_t slot, uint32_t slot_start_time_hr) +{ + uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr); + uint32_t t2 = (NFAPI_SFNSLOT2DEC(sfn, slot) * 500) + slot_time_us; + + if (0) + { + static uint32_t prev_t2 = 0; + + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(now_time_hr:%u sfn:%d slot:%d slot_start_time_Hr:%u) slot_time_us:%u t2:%u prev_t2:%u diff:%u\n", + __FUNCTION__, + now_time_hr, NFAPI_SFNSLOT2DEC(sfn, slot), slot_start_time_hr, + slot_time_us, + t2, + prev_t2, + t2-prev_t2); + + prev_t2 = t2; + } + + return t2; +} + uint32_t calculate_t3(uint16_t sfn_sf, uint32_t sf_start_time_hr) { uint32_t now_time_hr = pnf_get_current_time_hr(); @@ -1448,6 +2463,17 @@ uint32_t calculate_t3(uint16_t sfn_sf, uint32_t sf_start_time_hr) return t3; } +uint32_t calculate_nr_t3(uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr) +{ + uint32_t now_time_hr = pnf_get_current_time_hr(); + + uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr); + + uint32_t t3 = (NFAPI_SFNSLOT2DEC(sfn, slot) * 500) + slot_time_us; + + return t3; +} + void pnf_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time) { nfapi_dl_node_sync_t dl_node_sync; @@ -1498,6 +2524,60 @@ void pnf_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, u pnf_p7_pack_and_send_p7_message(pnf_p7, &(ul_node_sync.header), sizeof(ul_node_sync)); } + +void pnf_nr_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time) +{ + //printf("Received DL node sync"); + + nfapi_nr_dl_node_sync_t dl_node_sync; + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_NODE_SYNC Received\n"); + + if (pRecvMsg == NULL || pnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + return; + } + + // unpack the message + if (nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &dl_node_sync, sizeof(dl_node_sync), &pnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + return; + } + + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return; + } + + + if (dl_node_sync.delta_sfn_slot != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Will shift Slot timing by %d on next slot\n", dl_node_sync.delta_sfn_slot); + + pnf_p7->slot_shift = dl_node_sync.delta_sfn_slot; + } + + nfapi_nr_ul_node_sync_t ul_node_sync; + memset(&ul_node_sync, 0, sizeof(ul_node_sync)); + ul_node_sync.header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC; + ul_node_sync.header.phy_id = dl_node_sync.header.phy_id; + ul_node_sync.t1 = dl_node_sync.t1; + ul_node_sync.t2 = calculate_nr_t2(rx_hr_time, pnf_p7->sfn,pnf_p7->slot, pnf_p7->slot_start_time_hr); + ul_node_sync.t3 = calculate_nr_t3(pnf_p7->sfn,pnf_p7->slot, pnf_p7->slot_start_time_hr); + + if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); + return; + } + + pnf_nr_p7_pack_and_send_p7_message(pnf_p7, &(ul_node_sync.header), sizeof(ul_node_sync)); + //printf("\nSSent UL Node Sync sfn:%d,slot:%d\n",pnf_p7->sfn,pnf_p7->slot); +} + void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time) { nfapi_p7_message_header_t header; @@ -1528,7 +2608,6 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, case NFAPI_DL_NODE_SYNC: pnf_handle_dl_node_sync(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time); break; - case NFAPI_DL_CONFIG_REQUEST: pnf_handle_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7); break; @@ -1544,7 +2623,7 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, case NFAPI_TX_REQUEST: pnf_handle_tx_request(pRecvMsg, recvMsgLen, pnf_p7); break; - + case NFAPI_LBT_DL_CONFIG_REQUEST: pnf_handle_lbt_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7); break; @@ -1569,6 +2648,66 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, } } +void pnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time) +{ + nfapi_p7_message_header_t header; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return; + } + + // unpack the message header + if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &pnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + // ensure the message is sensible + if (recvMsgLen < 8 || pRecvMsg == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen); + return; + } + + switch (header.message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC: + pnf_nr_handle_dl_node_sync(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time); + break; + + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + //printf("\nEntering pnf_handle_dl_tti_request sfn=%d,slot=%d \n",pnf_p7->sfn,pnf_p7->slot); + pnf_handle_dl_tti_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + pnf_handle_ul_tti_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + pnf_handle_ul_dci_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + pnf_handle_tx_data_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + default: + { + if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + header.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + pnf_handle_p7_vendor_extension(pRecvMsg, recvMsgLen, pnf_p7, header.message_id); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P7 Unknown message ID %d\n", __FUNCTION__, header.message_id); + } + } + break; + } +} + void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time) { nfapi_p7_message_header_t messageHeader; @@ -1674,6 +2813,114 @@ void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, ui pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, 1000); } + +void pnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time) +{ + nfapi_p7_message_header_t messageHeader; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "pnf_handle_p7_message: invalid input params (%d %d %d)\n", pRecvMsg, recvMsgLen, pnf_p7); + return; + } + + // unpack the message header + if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p7_message_header_t), &pnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + uint8_t m = NFAPI_P7_GET_MORE(messageHeader.m_segment_sequence); + uint8_t sequence_num = NFAPI_P7_GET_SEQUENCE(messageHeader.m_segment_sequence); + uint8_t segment_num = NFAPI_P7_GET_SEGMENT(messageHeader.m_segment_sequence); + + if(pnf_p7->_public.checksum_enabled) + { + uint32_t checksum = nfapi_p7_calculate_checksum(pRecvMsg, recvMsgLen); + if(checksum != messageHeader.checksum) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d\n", checksum, messageHeader.checksum); + return; + } + } + + if(m == 0 && segment_num == 0) + { + // we have a complete message + // ensure the message is sensible + if (recvMsgLen < 8 || pRecvMsg == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen); + return; + } + + pnf_nr_dispatch_p7_message(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time); + } + else + { + pnf_p7_rx_message_t* rx_msg = pnf_p7_rx_reassembly_queue_add_segment(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, sequence_num, segment_num, m, pRecvMsg, recvMsgLen); + + if(rx_msg->num_segments_received == rx_msg->num_segments_expected) + { + // send the buffer on + uint16_t i = 0; + uint16_t length = 0; + for(i = 0; i < rx_msg->num_segments_expected; ++i) + { + length += rx_msg->segments[i].length - (i > 0 ? NFAPI_P7_HEADER_LENGTH : 0); + } + + if(pnf_p7->reassemby_buffer_size < length) + { + pnf_p7_free(pnf_p7, pnf_p7->reassemby_buffer); + pnf_p7->reassemby_buffer = 0; + } + + if(pnf_p7->reassemby_buffer == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Resizing PNF_P7 Reassembly buffer %d->%d\n", pnf_p7->reassemby_buffer_size, length); + pnf_p7->reassemby_buffer = (uint8_t*)pnf_p7_malloc(pnf_p7, length); + + if(pnf_p7->reassemby_buffer == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate PNF_P7 reassemby buffer len:%d\n", length); + return; + } + memset(pnf_p7->reassemby_buffer, 0, length); + pnf_p7->reassemby_buffer_size = length; + } + + uint16_t offset = 0; + for(i = 0; i < rx_msg->num_segments_expected; ++i) + { + if(i == 0) + { + memcpy(pnf_p7->reassemby_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length); + offset += rx_msg->segments[i].length; + } + else + { + memcpy(pnf_p7->reassemby_buffer + offset, rx_msg->segments[i].buffer + NFAPI_P7_HEADER_LENGTH, rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH); + offset += rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH; + } + } + + + pnf_nr_dispatch_p7_message(pnf_p7->reassemby_buffer, length, pnf_p7, rx_msg->rx_hr_time); + + + // delete the structure + pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7, &(pnf_p7->reassembly_queue), rx_msg); + } + } + + pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, 1000); + +} + + void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time) { int recvfrom_result = 0; @@ -1708,6 +2955,7 @@ void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time) if(recvfrom_result > 0) { pnf_handle_p7_message(pnf_p7->rx_message_buffer, recvfrom_result, pnf_p7, now_hr_time); + //printf("\npnf_handle_p7_message sfn=%d,slot=%d\n",pnf_p7->sfn,pnf_p7->slot); } } else if(recvfrom_result == 0) @@ -1735,6 +2983,70 @@ void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time) while(recvfrom_result > 0); } +void pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time) +{ + int recvfrom_result = 0; + struct sockaddr_in remote_addr; + socklen_t remote_addr_size = sizeof(remote_addr); + remote_addr.sin_family = 2; //hardcoded + + do + { + // peek the header + uint8_t header_buffer[NFAPI_P7_HEADER_LENGTH]; + recvfrom_result = recvfrom(pnf_p7->p7_sock, header_buffer, NFAPI_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size); + + if(recvfrom_result > 0) + { + // get the segment size + nfapi_p7_message_header_t header; + nfapi_p7_message_header_unpack(header_buffer, NFAPI_P7_HEADER_LENGTH, &header, 34, 0); + + // resize the buffer if we have a large segment + if(header.message_length > pnf_p7->rx_message_buffer_size) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length); + pnf_p7->rx_message_buffer = realloc(pnf_p7->rx_message_buffer, header.message_length); + pnf_p7->rx_message_buffer_size = header.message_length; + } + + // read the segment + recvfrom_result = recvfrom(pnf_p7->p7_sock, pnf_p7->rx_message_buffer, header.message_length, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size); + + now_hr_time = pnf_get_current_time_hr(); //DJP - moved to here - get closer timestamp??? + + if(recvfrom_result > 0) + { + pnf_nr_handle_p7_message(pnf_p7->rx_message_buffer, recvfrom_result, pnf_p7, now_hr_time); + //printf("\npnf_handle_p7_message sfn=%d,slot=%d\n",pnf_p7->sfn,pnf_p7->slot); + } + } + else if(recvfrom_result == 0) + { + // recv zero length message + recvfrom_result = recvfrom(pnf_p7->p7_sock, header_buffer, 0, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size); + } + + if(recvfrom_result == -1) + { + if(errno == EAGAIN || errno == EWOULDBLOCK) + { + // return to the select + //NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom would block :%d\n", __FUNCTION__, errno); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom failed errno:%d\n", __FUNCTION__, errno); + } + } + + // need to update the time as we would only use the value from the + // select + } + while(recvfrom_result > 0); +} + + int pnf_p7_message_pump(pnf_p7_t* pnf_p7) { @@ -1786,7 +3098,7 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7) struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - addr.sin_port = htons(pnf_p7->_public.local_p7_port); + addr.sin_port = pnf_p7->_public.local_p7_port; if(pnf_p7->_public.local_p7_addr == 0) { @@ -1827,6 +3139,9 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7) uint32_t now_hr_time = pnf_get_current_time_hr(); + + + if(selectRetval == 0) { // timeout @@ -1845,7 +3160,8 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7) continue; } - if(FD_ISSET(pnf_p7->p7_sock, &rfds)) + if(FD_ISSET(pnf_p7->p7_sock, &rfds)) + { pnf_nfapi_p7_read_dispatch_message(pnf_p7, now_hr_time); } @@ -1870,3 +3186,143 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7) return 0; } + +int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7) +{ + + // initialize the mutex lock + if(pthread_mutex_init(&(pnf_p7->mutex), NULL) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 mutex init: %d\n", errno); + return -1; + } + + if(pthread_mutex_init(&(pnf_p7->pack_mutex), NULL) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 mutex init: %d\n", errno); + return -1; + } + + // create the pnf p7 socket + if ((pnf_p7->p7_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno); + return -1; + } + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 socket created (%d)...\n", pnf_p7->p7_sock); + + // configure the UDP socket options + int reuseaddr_enable = 1; + if (setsockopt(pnf_p7->p7_sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_enable, sizeof(int)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (SOL_SOCKET, SO_REUSEADDR) failed errno: %d\n", errno); + return -1; + } + +/* + int reuseport_enable = 1; + if (setsockopt(pnf_p7->p7_sock, SOL_SOCKET, SO_REUSEPORT, &reuseport_enable, sizeof(int)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (SOL_SOCKET, SO_REUSEPORT) failed errno: %d\n", errno); + return -1; + } +*/ + + int iptos_value = FAPI2_IP_DSCP << 2; + if (setsockopt(pnf_p7->p7_sock, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (IPPROTO_IP, IP_TOS) failed errno: %d\n", errno); + return -1; + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = pnf_p7->_public.local_p7_port; + + if(pnf_p7->_public.local_p7_addr == 0) + { + addr.sin_addr.s_addr = INADDR_ANY; + } + else + { + //addr.sin_addr.s_addr = inet_addr(pnf_p7->_public.local_p7_addr); + if(inet_aton(pnf_p7->_public.local_p7_addr, &addr.sin_addr) == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "inet_aton failed\n"); + } + } + + + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 binding %d too %s:%d\n", pnf_p7->p7_sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + if (bind(pnf_p7->p7_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF_P7 bind error fd:%d errno: %d\n", pnf_p7->p7_sock, errno); + return -1; + } + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 bind succeeded...\n"); + + while(pnf_p7->terminate == 0) + { + fd_set rfds; + int selectRetval = 0; + + // select on a timeout and then get the message + FD_ZERO(&rfds); + FD_SET(pnf_p7->p7_sock, &rfds); + + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + selectRetval = select(pnf_p7->p7_sock+1, &rfds, NULL, NULL, &timeout); + + uint32_t now_hr_time = pnf_get_current_time_hr(); + + + + + if(selectRetval == 0) + { + // timeout + continue; + } + else if (selectRetval == -1 && (errno == EINTR)) + { + // interrupted by signal + NFAPI_TRACE(NFAPI_TRACE_WARN, "PNF P7 Signal Interrupt %d\n", errno); + continue; + } + else if (selectRetval == -1) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "PNF P7 select() failed\n"); + sleep(1); + continue; + } + + if(FD_ISSET(pnf_p7->p7_sock, &rfds)) + + { + pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7, now_hr_time); + } + } + NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF_P7 Terminating..\n"); + + // close the connection and socket + if (close(pnf_p7->p7_sock) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "close failed errno: %d\n", errno); + } + + if(pthread_mutex_destroy(&(pnf_p7->pack_mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "mutex destroy failed errno: %d\n", errno); + } + + if(pthread_mutex_destroy(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "mutex destroy failed errno: %d\n", errno); + } + + return 0; +} diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c index 24e73ae9b3..efcb60ce96 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c @@ -31,7 +31,7 @@ nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create() _this->_public.segment_size = 1400; _this->max_num_segments = 8; - _this->_public.subframe_buffer_size = 8; + _this->_public.subframe_buffer_size = 8;// TODO: Initialize the slot_buffer size _this->_public.timing_info_mode_periodic = 1; _this->_public.timing_info_period = 32; _this->_public.timing_info_mode_aperiodic = 1; @@ -76,6 +76,26 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config) return 0; } +int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config) +{ + // Verify that config is not null + if(config == 0) + return -1; + + // Make sure to set the defined trace function before using NFAPI_TRACE + if(config->trace) + nfapi_trace_g = config->trace; + + pnf_p7_t* _this = (pnf_p7_t*)(config); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + + pnf_nr_p7_message_pump(_this); + + return 0; +} + + int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config) { // Verify that config is not null @@ -88,6 +108,16 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config) return 0; } +int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot) +{ + // Verify that config is not null + if(config == 0) + return -1; + + pnf_p7_t* _this = (pnf_p7_t*)(config); + + return pnf_p7_slot_ind(_this, phy_id, sfn, slot); +} int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf) { diff --git a/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c b/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c index d2ab031ad4..bd6bedbea5 100644 --- a/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c +++ b/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c @@ -48,6 +48,9 @@ typedef struct phy_info uint8_t enabled; uint16_t phy_id; uint16_t sfn_sf; + uint16_t sfn; + uint16_t slot; + pthread_t thread; @@ -1207,6 +1210,12 @@ void send_dl_subframe_msgs_interleaved(int p7Sock, int phy_id, struct sockaddr_i //free(req.tx_request_body.tx_pdu_list); } +void send_slot_indication(phy_info_t* phy_info) +{ + // DONE: add sfn and slot as members in the phy_info + nfapi_pnf_p7_slot_ind(phy_info->config, phy_info->phy_id, phy_info->sfn, phy_info->slot); +} + void send_subframe_indication(phy_info_t* phy_info) { nfapi_pnf_p7_subframe_ind(phy_info->config, phy_info->phy_id, phy_info->sfn_sf); diff --git a/nfapi/open-nFAPI/vnf/inc/vnf.h b/nfapi/open-nFAPI/vnf/inc/vnf.h index 4fd8d2b91d..b16b842606 100644 --- a/nfapi/open-nFAPI/vnf/inc/vnf.h +++ b/nfapi/open-nFAPI/vnf/inc/vnf.h @@ -35,9 +35,13 @@ typedef struct int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len); +int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len); + int vnf_pack_and_send_p4_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len); int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf); +int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf); + void nfapi_vnf_phy_info_list_add(nfapi_vnf_config_t* config, nfapi_vnf_phy_info_t* info); nfapi_vnf_phy_info_t* nfapi_vnf_phy_info_list_find(nfapi_vnf_config_t* config, uint16_t phy_id); diff --git a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h index fc2ab4e6b5..ad1c5e7944 100644 --- a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h +++ b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h @@ -77,6 +77,9 @@ typedef struct nfapi_vnf_p7_connection_info { int32_t sf_offset_filtered; int32_t sf_offset_trend; int32_t sf_offset; + int32_t slot_offset; + int32_t slot_offset_trend; + int32_t slot_offset_filtered; uint16_t zero_count; int32_t adjustment; int32_t insync_minor_adjustment; @@ -85,8 +88,10 @@ typedef struct nfapi_vnf_p7_connection_info { uint32_t previous_t1; uint32_t previous_t2; int32_t previous_sf_offset_filtered; - + int32_t previous_slot_offset_filtered; int sfn_sf; + int sfn; + int slot; int socket; struct sockaddr_in local_addr; @@ -111,6 +116,7 @@ typedef struct { nfapi_vnf_p7_connection_info_t* p7_connections; int socket; uint32_t sf_start_time_hr; + uint32_t slot_start_time_hr; uint8_t* rx_message_buffer; // would this be better put in the p7 conenction info? uint16_t rx_message_buffer_size; @@ -120,14 +126,19 @@ uint32_t vnf_get_current_time_hr(void); uint16_t increment_sfn_sf(uint16_t sfn_sf); int vnf_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info); +int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info); + int send_mac_subframe_indications(vnf_p7_t* config); +int send_mac_slot_indications(vnf_p7_t* config); int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7 ); +int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7 ); void vnf_p7_connection_info_list_add(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* node); nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_find(vnf_p7_t* vnf_p7, uint16_t phy_id); nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_delete(vnf_p7_t* vnf_p7, uint16_t phy_id); int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header); +int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header); void vnf_p7_release_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header); void vnf_p7_release_pdu(vnf_p7_t* vnf_p7, void* pdu); diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h index 5abf6b75c3..518b01864e 100644 --- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -19,6 +19,7 @@ #include "nfapi_interface.h" #include "nfapi_nr_interface_scf.h" +#include "nfapi_nr_interface.h" #include "debug.h" @@ -120,6 +121,7 @@ typedef struct nfapi_vnf_config * * \todo Do we need to send the address information of the PNF? */ + int (*pnf_nr_connection_indication)(nfapi_vnf_config_t* config, int p5_idx); int (*pnf_connection_indication)(nfapi_vnf_config_t* config, int p5_idx); /*! \brief Callback indicating that a pnf has lost connection @@ -160,6 +162,7 @@ typedef struct nfapi_vnf_config * then the substructure pointers should be set to 0 and then the client should * use the codec_config.deallocate function to release it at a future point */ + int (*pnf_nr_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_response_t* resp); int (*pnf_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp); /*! A callback for the PNF_CONFIG.resp @@ -182,7 +185,8 @@ typedef struct nfapi_vnf_config * use the codec_config.deallocate function to release it at a future point */ int (*pnf_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp); - + int (*pnf_nr_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_config_response_t* resp); + /*! A callback for the PNF_START.resp * \param config A pointer to the vnf configuration * \param p5_idx The p5 index used to indicate a particular pnf p5 connection @@ -203,7 +207,8 @@ typedef struct nfapi_vnf_config * use the codec_config.deallocate function to release it at a future point */ int (*pnf_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp); - + int (*pnf_nr_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_start_response_t* resp); + /*! A callback for the PNF_STOP.resp * \param config A pointer to the vnf configuration * \param p5_idx The p5 index used to indicate a particular pnf p5 connection @@ -249,6 +254,7 @@ typedef struct nfapi_vnf_config * use the codec_config.deallocate function to release it at a future point */ int (*param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* resp); + int (*nr_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_response_scf_t* resp); /*! A callback for the CONFIG.response * \param config A pointer to the vnf configuration @@ -266,8 +272,9 @@ typedef struct nfapi_vnf_config * then the substructure pointers should be set to 0 and then the client should * use the codec_config.deallocate function to release it at a future point */ + int (*nr_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_response_scf_t* resp); int (*config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp); - + /*! A callback for the START.resp * \param config A pointer to the vnf configuration * \param p5_idx The p5 index used to indicate a particular pnf p5 connection @@ -285,6 +292,7 @@ typedef struct nfapi_vnf_config * use the codec_config.deallocate function to release it at a future point */ int (*start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp); + int (*nr_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_response_scf_t* resp); /*! A callback for the STOP.resp * \param config A pointer to the vnf configuration @@ -469,6 +477,8 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config); * * This function will not return untill nfapi_vnf_stop is called */ +int nfapi_nr_vnf_start(nfapi_vnf_config_t* config); + int nfapi_vnf_start(nfapi_vnf_config_t* config); /*! Stop the VNF library. @@ -500,6 +510,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy * \return 0 means success, -1 failure */ int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req); +int nfapi_nr_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_request_t* req); /*! Send the PNF_CONFIG.request * \param config A pointer to a vnf config @@ -508,6 +519,7 @@ int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_pa * \return 0 means success, -1 failure */ int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_config_request_t* req); +int nfapi_nr_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_nr_pnf_config_request_t* req); /*! Send the PNF_START.request * \param config A pointer to a vnf config @@ -516,6 +528,7 @@ int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_co * \return 0 means success, -1 failure */ int nfapi_vnf_pnf_start_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_start_request_t* req); +int nfapi_nr_vnf_pnf_start_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_nr_pnf_start_request_t* req); /*! Send the PNF_STOP.request * \param config A pointer to a vnf config @@ -532,6 +545,7 @@ int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_stop * \return 0 means success, -1 failure */ int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req); +int nfapi_nr_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_request_scf_t* req); /*! Send the CONFIG.request * \param config A pointer to a vnf config @@ -539,6 +553,7 @@ int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_requ * \param req A pointer to a CONFIG.request message structure * \return 0 means success, -1 failure */ +int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_request_scf_t* req); int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req); /*! Send the START.request @@ -548,6 +563,7 @@ int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_re * \return 0 means success, -1 failure */ int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t* req); +int nfapi_nr_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_request_scf_t* req); /*! Send the STOP.request * \param config A pointer to a vnf config @@ -692,6 +708,7 @@ typedef struct nfapi_vnf_p7_config */ int (*subframe_indication)(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf); + int (*slot_indication)(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn, uint16_t slot); /*! A callback for the HARQ.indication * \param config A pointer to the vnf p7 configuration @@ -885,6 +902,8 @@ void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config); */ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config); +int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config); + /*! Stop the VNF P7 library. * \param config A pointer to an vnf p7 configuration structure @@ -950,7 +969,7 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti * may be released after this function call has returned or at a later pointer */ int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req); - +int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req); /*! Send the HI_DCI0.request * \param config A pointer to the vnf p7 configuration * \param req A data structure for the decoded HI_DCI0.request. @@ -960,7 +979,7 @@ int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_re * may be released after this function call has returned or at a later pointer */ int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req); - +int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req); /*! Send the TX.req * \param config A pointer to the vnf p7 configuration * \param req A data structure for the decoded HI_DCI0.request. @@ -970,7 +989,7 @@ int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_reques * may be released after this function call has returned or at a later pointer */ int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req); - +int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req); /*! Send the LBT_DL_CONFIG.requst * \param config A pointer to the vnf p7 configuration * \param req A data structure for the decoded LBT_DL_CONFIG.request. diff --git a/nfapi/open-nFAPI/vnf/src/vnf.c b/nfapi/open-nFAPI/vnf/src/vnf.c index 6800ee21d2..7fee47d6d5 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf.c +++ b/nfapi/open-nFAPI/vnf/src/vnf.c @@ -21,9 +21,12 @@ #include #include #include +#include #include #include "vnf.h" +#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" void* vnf_malloc(nfapi_vnf_config_t* config, size_t size) @@ -101,6 +104,39 @@ nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5 return 0; } +void vnf_nr_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_PARAM.reponse\n"); + + nfapi_nr_pnf_param_response_t msg; + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + // Invoke the call back + if(config->pnf_nr_param_resp) + { + (config->pnf_nr_param_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) { // ensure it's valid @@ -134,6 +170,40 @@ void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_con } } + +void vnf_nr_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_CONFIG_RESPONSE\n"); + + nfapi_nr_pnf_config_response_t msg; + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + // Invoke the call back + if(config->pnf_nr_config_resp) + { + (config->pnf_nr_config_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + void vnf_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) { // ensure it's valid @@ -167,6 +237,38 @@ void vnf_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_co } } +void vnf_nr_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_START_RESPONSE\n"); + + nfapi_nr_pnf_start_response_t msg; + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + if(config->pnf_nr_start_resp) + { + (config->pnf_nr_start_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + void vnf_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) { // ensure it's valid @@ -298,8 +400,113 @@ void vnf_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_ } } +void vnf_nr_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PARAM_RESPONSE\n"); + + nfapi_nr_param_response_scf_t msg; + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { + + if (msg.error_code == NFAPI_NR_PARAM_MSG_OK) + { + nfapi_vnf_phy_info_t* phy_info = nfapi_vnf_phy_info_list_find(config, msg.header.phy_id); + + if(msg.nfapi_config.p7_pnf_address_ipv4.tl.tag) + { + struct sockaddr_in sockAddr; + + (void)memcpy(&sockAddr.sin_addr.s_addr, msg.nfapi_config.p7_pnf_address_ipv4.address, NFAPI_IPV4_ADDRESS_LENGTH); + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv4 address: %s\n", inet_ntoa(sockAddr.sin_addr)); + + // store address + phy_info->p7_pnf_address.sin_addr = sockAddr.sin_addr; + } + + if(msg.nfapi_config.p7_pnf_address_ipv6.tl.tag) + { + struct sockaddr_in6 sockAddr6; + char addr6[64]; + (void)memcpy(&sockAddr6.sin6_addr, msg.nfapi_config.p7_pnf_address_ipv6.address, NFAPI_IPV6_ADDRESS_LENGTH); + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv6 address: %s\n", inet_ntop(AF_INET6, &sockAddr6.sin6_addr, addr6, sizeof(addr6))); + } + + if (msg.nfapi_config.p7_pnf_port.tl.tag) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 Port: %d\n", msg.nfapi_config.p7_pnf_port.value); + + // store port + phy_info->p7_pnf_address.sin_port = htons(msg.nfapi_config.p7_pnf_port.value); + } + } + + if(config->nr_param_resp) + { + (config->nr_param_resp)(config, p5_idx, &msg); + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + + +void vnf_nr_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received CONFIG_RESPONSE\n"); + + nfapi_nr_config_response_scf_t msg; + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >=0 ) + { + // check the error code: + + if (msg.error_code == NFAPI_NR_CONFIG_MSG_OK){ + if(config->nr_config_resp) + { + (config->nr_config_resp)(config, p5_idx, &msg); + } + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + void vnf_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) { + // ensure it's valid if (pRecvMsg == NULL || config == NULL) { @@ -314,9 +521,13 @@ void vnf_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config // unpack the message if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >=0 ) { - if(config->config_resp) - { - (config->config_resp)(config, p5_idx, &msg); + // check the error code: + + if (msg.error_code == NFAPI_MSG_OK){ + if(config->config_resp) + { + (config->config_resp)(config, p5_idx, &msg); + } } } else @@ -362,6 +573,40 @@ void vnf_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_ } } +void vnf_nr_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) +{ + // ensure it's valid + if (pRecvMsg == NULL || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received START_RESPONSE\n"); + + nfapi_nr_start_response_scf_t msg; + + // unpack the message + if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0) + { // check the error code + if (msg.error_code == NFAPI_NR_START_MSG_OK){ + if(config->nr_start_resp) + { + (config->nr_start_resp)(config, p5_idx, &msg); + } + } + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + // make sure to release any dyanmic part of the message + if(msg.vendor_extension) + config->codec_config.deallocate(msg.vendor_extension); + } +} + void vnf_handle_stop_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx) { @@ -811,6 +1056,74 @@ void vnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, nfapi_vnf_confi } } +void vnf_nr_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config) +{ + nfapi_p4_p5_message_header_t messageHeader; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH || config == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p4_p5_message: invalid input params\n"); + return; + } + + // unpack the message header + if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &config->codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + switch (messageHeader.message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE: + vnf_nr_handle_pnf_param_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE: + vnf_nr_handle_pnf_config_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE: + vnf_nr_handle_pnf_start_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_PNF_STOP_RESPONSE: + vnf_handle_pnf_stop_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE: + vnf_nr_handle_param_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: + vnf_nr_handle_config_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE: + vnf_nr_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE: + vnf_handle_stop_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + default: + { + if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + vnf_handle_vendor_extension(pRecvMsg, recvMsgLen, config, p5_idx, messageHeader.message_id); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id); + } + } + break; + } +} + void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config) { nfapi_p4_p5_message_header_t messageHeader; @@ -926,6 +1239,137 @@ void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_ break; } } + + +int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf) +{ + if(1) + { + int socket_connected = 1; + + // 1. Peek the message header + // 2. If the message is larger than the stack buffer then create a dynamic buffer + // 3. Read the buffer + // 4. Handle the p5 message + + uint32_t header_buffer_size = NFAPI_HEADER_LENGTH; + uint8_t header_buffer[header_buffer_size]; + + uint32_t stack_buffer_size = 32; //should it be the size of then sctp_notificatoin structure + uint8_t stack_buffer[stack_buffer_size]; + + uint8_t* dynamic_buffer = 0; + + uint8_t* read_buffer = &stack_buffer[0]; + uint32_t message_size = 0; + + struct sockaddr_in addr; + socklen_t addr_len = sizeof(addr); + + struct sctp_sndrcvinfo sndrcvinfo; + (void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); + + { + int flags = MSG_PEEK; + message_size = sctp_recvmsg(pnf->p5_sock, header_buffer, header_buffer_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags); + + if(message_size == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to peek sctp message size errno:%d\n", errno); + return 0; + } + + nfapi_p4_p5_message_header_t header; + int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0); + if(unpack_result < 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to decode message header %d\n", unpack_result); + return 0; + } + message_size = header.message_length; + + // now have the size of the mesage + } + + if(message_size > stack_buffer_size) + { + dynamic_buffer = (uint8_t*)malloc(message_size); + + if(dynamic_buffer == NULL) + { + // todo : add error mesage + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size); + return -1; + } + + read_buffer = dynamic_buffer; + } + + { + int flags = 0; + (void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); + + int recvmsg_result = sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags); + if(recvmsg_result == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno); + } + else + { + if (flags & MSG_NOTIFICATION) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + + // todo - handle the events + } + else + { + /* + NFAPI_TRACE(NFAPI_TRACE_INFO, "Received message fd:%d from %s:%u assoc:%d on stream %d, PPID %d, length %d, flags 0x%x\n", + pnf->p5_sock, + inet_ntoa(addr.sin_addr), + ntohs(addr.sin_port), + sndrcvinfo.sinfo_assoc_id, + sndrcvinfo.sinfo_stream, + ntohl(sndrcvinfo.sinfo_ppid), + message_size, + flags); + */ + + // handle now if complete message in one or more segments + if ((flags & 0x80) == 0x80) + { + // printf("\nVNF RECEIVES:\n"); + // for(int i=0; ip5_idx, config); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags); + + // assume socket disconnected + NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n"); + socket_connected = 0; + } + + + } + } + } + + if(dynamic_buffer) + { + free(dynamic_buffer); + } + + return socket_connected; + } +} + int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf) { if(1) @@ -1024,6 +1468,12 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* // handle now if complete message in one or more segments if ((flags & 0x80) == 0x80) { + // printf("\nVNF RECEIVES:\n"); + // for(int i=0; ip5_idx, config); } else @@ -1051,6 +1501,12 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len, uint8_t stream) { + // printf("\n MESSAGE SENT: \n"); + // for(int i=0; ip5_sock, msg, len, (struct sockaddr*)&pnf->p5_pnf_sockaddr, sizeof(pnf->p5_pnf_sockaddr),1, 0, stream, 0, 4); @@ -1071,6 +1527,29 @@ static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len, return 0; } +int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len) +{ + nfapi_vnf_pnf_info_t* pnf = nfapi_vnf_pnf_list_find(&(vnf->_public), p5_idx); + + if(pnf) + { + // pack the message for transmission + int packedMessageLength = nfapi_nr_p5_message_pack(msg, msg_len, vnf->tx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config); + + if (packedMessageLength < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength); + return -1; + } + return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx); + return -1; + } +} + int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len) { diff --git a/nfapi/open-nFAPI/vnf/src/vnf_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_interface.c index 59d7f3eb4f..084c4fa485 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_interface.c @@ -63,6 +63,418 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config) free(config); } +int nfapi_nr_vnf_start(nfapi_vnf_config_t* config) +{ + // Verify that config is not null + if(config == 0) + return -1; + + // Make sure to set the defined trace function before using NFAPI_TRACE + if(config->trace) + nfapi_trace_g = (nfapi_trace_fn_t)config->trace; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); + + int p5ListenSock, p5Sock; + + struct sockaddr_in addr; + socklen_t addrSize; + + struct sockaddr_in6 addr6; + + struct sctp_event_subscribe events; + struct sctp_initmsg initMsg; + int noDelay; + + (void)memset(&addr, 0, sizeof(struct sockaddr_in)); + (void)memset(&addr6, 0, sizeof(struct sockaddr_in6)); + (void)memset(&events, 0, sizeof(struct sctp_event_subscribe)); + (void)memset(&initMsg, 0, sizeof(struct sctp_initmsg)); + + vnf_t* vnf = (vnf_t*)(config); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Starting P5 VNF connection on port %u\n", config->vnf_p5_port); + + /* + char * host = 0; + char * port = "4242"; + struct addrinfo hints; + bzero(&hints, sizeof(struct addrinfo)); + //hints.ai_flags=AI_PASSIVE; + //hints.ai_flags=AI_DEFAULT; + hints.ai_family=AF_UNSPEC; + //hints.ai_family=AF_INET6; + hints.ai_socktype=SOCK_STREAM; + //hints.ai_protocol=IPPROTO_SCTP + + struct addrinfo *aiHead = 0; + + + + int result = getaddrinfo(host, port, &hints, &aiHead); + NFAPI_TRACE(NFAPI_TRACE_INFO, "getaddrinfo return %d %d\n", result, errno); + + while(aiHead->ai_next != NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "addr info %d (IP %d UDP %d SCTP %d)\n %d (%d)\n", + aiHead->ai_protocol, IPPROTO_IP, IPPROTO_UDP, IPPROTO_SCTP, + aiHead->ai_flags, AI_PASSIVE); + + char hostBfr[ NI_MAXHOST ]; + char servBfr[ NI_MAXSERV ]; + + getnameinfo(aiHead->ai_addr, + aiHead->ai_addrlen, + hostBfr, + sizeof( hostBfr ), + servBfr, + sizeof( servBfr ), + NI_NUMERICHOST | NI_NUMERICSERV ); + + switch(aiHead->ai_family) + { + case PF_INET: + { + struct sockaddr_in *pSadrIn = (struct sockaddr_in*) aiHead->ai_addr; + printf( + " ai_addr = sin_family: %d (AF_INET = %d, " + "AF_INET6 = %d)\n" + " sin_addr: %s\n" + " sin_port: %s\n", + pSadrIn->sin_family, + AF_INET, + AF_INET6, + hostBfr, + servBfr ); + } + break; + case PF_INET6: + { + struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6*) aiHead->ai_addr; + fprintf( stderr, + " ai_addr = sin6_family: %d (AF_INET = %d, " + "AF_INET6 = %d) \n" + " sin6_addr: %s\n" + " sin6_port: %s\n" + " sin6_flowinfo: %d\n" + " sin6_scope_id: %d\n", + pSadrIn6->sin6_family, + AF_INET, + AF_INET6, + hostBfr, + servBfr, + pSadrIn6->sin6_flowinfo, + pSadrIn6->sin6_scope_id); + } + break; + default: + NFAPI_TRACE(NFAPI_TRACE_INFO, "Not ment to be here\n"); + break; + } + + aiHead = aiHead->ai_next; + } + */ + + { + int protocol; + int domain; + + if (vnf->sctp) + protocol = IPPROTO_SCTP; + else + protocol = IPPROTO_IP; + + if(config->vnf_ipv6) + { + domain = PF_INET6; + } + else + { + domain = AF_INET; + } + + // open the SCTP socket + if ((p5ListenSock = socket(domain, SOCK_STREAM, protocol)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P5 socket errno: %d\n", errno); + return 0; + } + NFAPI_TRACE(NFAPI_TRACE_INFO, "P5 socket created... %d\n", p5ListenSock); + } + + if (vnf->sctp) + { + // configure for MSG_NOTIFICATION + if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(struct sctp_event_subscribe)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_EVENTS) errno: %d\n", errno); + close(p5ListenSock); + return 0; + } + NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF Setting the SCTP_INITMSG\n"); + // configure the SCTP socket options + initMsg.sinit_num_ostreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater + initMsg.sinit_max_instreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater + if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_INITMSG) errno: %d\n", errno) + close(p5ListenSock); + return 0; + } + noDelay = 1; + if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_NODELAY, &noDelay, sizeof(noDelay)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (STCP_NODELAY) errno: %d\n", errno); + close(p5ListenSock); + return 0; + } + struct sctp_event_subscribe events; + memset( (void *)&events, 0, sizeof(events) ); + events.sctp_data_io_event = 1; + + if(setsockopt(p5ListenSock, SOL_SCTP, SCTP_EVENTS, (const void *)&events, sizeof(events)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt errno: %d\n", errno); + close(p5ListenSock); + return -1; + } + + } + + + if(config->vnf_ipv6) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV6 binding to port %d %d\n", config->vnf_p5_port, p5ListenSock); + addr6.sin6_family = AF_INET6; + addr6.sin6_port = htons(config->vnf_p5_port); + addr6.sin6_addr = in6addr_any; + + // bind to the configured address and port + if (bind(p5ListenSock, (struct sockaddr *)&addr6, sizeof(struct sockaddr_in6)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno); + close(p5ListenSock); + return 0; + } + } + else if(config->vnf_ipv4) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV4 binding to port %d\n", config->vnf_p5_port); + addr.sin_family = AF_INET; + addr.sin_port = htons(config->vnf_p5_port); + addr.sin_addr.s_addr = INADDR_ANY; + + // bind to the configured address and port + if (bind(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) + //if (sctp_bindx(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), SCTP_BINDX_ADD_ADDR) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno); + close(p5ListenSock); + return 0; + } + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "bind succeeded..%d.\n", p5ListenSock); + + // put the socket into listen mode + if (listen(p5ListenSock, 2) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After listen errno: %d\n", errno); + close(p5ListenSock); + return 0; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "listen succeeded...\n"); + + struct timeval tv; + fd_set read_fd_set; + + + int p5_idx = 0; + while(vnf->terminate == 0) + { + FD_ZERO(&read_fd_set); + + FD_SET(p5ListenSock, &read_fd_set); + int max_fd = p5ListenSock; + + tv.tv_sec = 5; + tv.tv_usec = 0; + + nfapi_vnf_pnf_info_t* pnf = config->pnf_list; + while(pnf != 0) + { + if(pnf->connected) + { + FD_SET(pnf->p5_sock, &read_fd_set); + if (pnf->p5_sock > max_fd) + { + max_fd = pnf->p5_sock; + } + } + + pnf = pnf->next; + } + + int select_result = select(max_fd + 1, &read_fd_set, 0, 0, &tv); + + if(select_result == -1) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "select result %d errno %d\n", select_result, errno); + close(p5ListenSock); + return 0; + } + else if(select_result) + { + if(FD_ISSET(p5ListenSock, &read_fd_set)) + { + addrSize = sizeof(struct sockaddr_in); + NFAPI_TRACE(NFAPI_TRACE_INFO, "Accepting connection from PNF...\n"); + + p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize); + + if (p5Sock < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to accept PNF connection reason:%d\n", errno); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF connection (fd:%d) accepted from %s:%d \n", p5Sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + nfapi_vnf_pnf_info_t* pnf = (nfapi_vnf_pnf_info_t*)malloc(sizeof(nfapi_vnf_pnf_info_t)); + NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf); + memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t)); + pnf->p5_sock = p5Sock; + pnf->p5_idx = p5_idx++; + pnf->p5_pnf_sockaddr = addr; + pnf->connected = 1; + + nfapi_vnf_pnf_list_add(config, pnf); + + // Inform mac that a pnf connection has been established + // todo : allow mac to 'accept' the connection. i.e. to + // reject it. + if(config->pnf_nr_connection_indication != 0) + { + (config->pnf_nr_connection_indication)(config, pnf->p5_idx); + } + + + // check the connection status + { + struct sctp_status status; + (void)memset(&status, 0, sizeof(struct sctp_status)); + socklen_t optLen = (socklen_t) sizeof(struct sctp_status); + if (getsockopt(p5Sock, IPPROTO_SCTP, SCTP_STATUS, &status, &optLen) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After getsockopt errno: %d\n", errno); + return -1; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Association ID = %d\n", status.sstat_assoc_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Receiver window size = %d\n", status.sstat_rwnd); + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF In Streams = %d\n", status.sstat_instrms); + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Out Streams = %d\n", status.sstat_outstrms); + + } + } + } + } + else + { + uint8_t delete_pnfs = 0; + + nfapi_vnf_pnf_info_t* pnf = config->pnf_list; + while(pnf != 0) + { + if(FD_ISSET(pnf->p5_sock, &read_fd_set)) + { + if(vnf_nr_read_dispatch_message(config, pnf) == 0) + { + if(config->pnf_disconnect_indication != 0) + { + (config->pnf_disconnect_indication)(config, pnf->p5_idx); + } + + close(pnf->p5_sock); + + pnf->to_delete = 1; + delete_pnfs = 1; + } + } + + pnf = pnf->next; + } + + if(delete_pnfs) + { + nfapi_vnf_pnf_info_t* pnf = config->pnf_list; + nfapi_vnf_pnf_info_t* prev = 0; + while(pnf != 0) + { + nfapi_vnf_pnf_info_t* curr = pnf; + + if(pnf->to_delete == 1) + { + if(prev == 0) + { + config->pnf_list = pnf->next; + } + else + { + prev->next = pnf->next; + } + + pnf = pnf->next; + + free(curr); + } + else + { + prev = pnf; + pnf = pnf->next; + } + + } + + } + } + + continue; + } + else + { + // timeout + + // Should we test for socket closure here every second? + + continue; + } + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Sock socket's\n"); + { + nfapi_vnf_pnf_info_t* curr = config->pnf_list; + while(curr != NULL) + { + if(config->pnf_disconnect_indication) + { + (config->pnf_disconnect_indication)(config, curr->p5_idx); + } + + close(curr->p5_sock); + curr = curr->next; + } + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Listen socket\n"); + close(p5ListenSock); + + return 0; + +} + int nfapi_vnf_start(nfapi_vnf_config_t* config) { // Verify that config is not null @@ -486,6 +898,16 @@ int nfapi_vnf_stop(nfapi_vnf_config_t* config) return 0; } +int nfapi_nr_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_param_request_t)); +} + int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req) { if(config == 0 || req == 0) @@ -496,6 +918,17 @@ int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_pa return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_param_request_t)); } +int nfapi_nr_vnf_pnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_config_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_config_request_t)); +} + + int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_request_t* req) { if(config == 0 || req == 0) @@ -516,6 +949,16 @@ int nfapi_vnf_pnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_st return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_start_request_t)); } +int nfapi_nr_vnf_pnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_start_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_start_request_t)); +} + int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_stop_request_t* req) { if(config == 0 || req == 0) @@ -526,6 +969,16 @@ int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_sto return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_stop_request_t)); } +int nfapi_nr_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_request_scf_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_param_request_scf_t)); +} + int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req) { if(config == 0 || req == 0) @@ -535,6 +988,38 @@ int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_requ return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_param_request_t)); } + +int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_request_scf_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + nfapi_vnf_phy_info_t* phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id); + + if(phy == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "%s failed to find phy information phy_id:%d\n", __FUNCTION__, req->header.phy_id); + return -1; + } + + // set the timing parameters + req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG; + req->nfapi_config.timing_window.value = phy->timing_window; + req->num_tlv++; + + req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG; + req->nfapi_config.timing_info_mode.value = phy->timing_info_mode; + req->num_tlv++; + + req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG; + req->nfapi_config.timing_info_period.value = phy->timing_info_period; + req->num_tlv++; + + return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_config_request_scf_t)); +} + int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req) { if(config == 0 || req == 0) @@ -565,7 +1050,8 @@ int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_re return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_config_request_t)); } -int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t* req) + +int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t * req) { if(config == 0 || req == 0) return -1; @@ -574,6 +1060,18 @@ int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_requ return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_start_request_t)); } + +int nfapi_nr_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_request_scf_t * req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_t* _this = (vnf_t*)(config); + + return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_start_request_scf_t)); +} + + int nfapi_vnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_stop_request_t* req) { if(config == 0 || req == 0) @@ -664,7 +1162,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy info->p5_idx = p5_idx; info->phy_id = vnf->next_phy_id++; - info->timing_window = 30; // This seems to override what gets set by the user - why??? + info->timing_window = 30; // This seems to override what gets set by the user - why??? //TODO: Change in NR in terms of microsecends,what should be the value? info->timing_info_mode = 0x03; info->timing_info_period = 128; diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index cff24500b6..ffbc5819bc 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -303,7 +303,7 @@ static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) { if(now_hr < sf_start_hr) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier that start of subframe\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe\n"); return 0; } else @@ -321,6 +321,28 @@ static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) } } +static uint32_t get_slot_time(uint32_t now_hr, uint32_t slot_start_hr) +{ + if(now_hr < slot_start_hr) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of slot\n"); + return 0; + } + else + { + uint32_t now_us = TIMEHR_USEC(now_hr); + uint32_t slot_start_us = TIMEHR_USEC(slot_start_hr); + + // if the us have wrapped adjust for it + if(now_hr < slot_start_us) + { + now_us += 1000000; + } + + return now_us - slot_start_us; + } +} + uint32_t calculate_t1(uint16_t sfn_sf, uint32_t sf_start_time_hr) { uint32_t now_time_hr = vnf_get_current_time_hr(); @@ -332,6 +354,17 @@ uint32_t calculate_t1(uint16_t sfn_sf, uint32_t sf_start_time_hr) return t1; } +uint32_t calculate_nr_t1(uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr) +{ + uint32_t now_time_hr = vnf_get_current_time_hr(); + + uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr); + + uint32_t t1 = (NFAPI_SFNSLOT2DEC(sfn,slot) * 500) + slot_time_us; + + return t1; +} + uint32_t calculate_t4(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_time_hr) { @@ -343,15 +376,25 @@ uint32_t calculate_t4(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_t } +uint32_t calculate_nr_t4(uint32_t now_time_hr, uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr) +{ + uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr); -uint32_t calculate_transmit_timestamp(uint16_t sfn_sf, uint32_t sf_start_time_hr) + uint32_t t4 = (NFAPI_SFNSLOT2DEC(sfn,slot) * 500) + slot_time_us; + + return t4; + +} + + +uint32_t calculate_transmit_timestamp(uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr) { uint32_t now_time_hr = vnf_get_current_time_hr(); - uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); - - uint32_t tt = (NFAPI_SFNSF2DEC(sfn_sf) * 1000) + sf_time_us; + uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr); + uint32_t tt = (NFAPI_SFNSLOT2DEC(sfn, slot) * 500) + slot_time_us; + return tt; } @@ -367,6 +410,27 @@ uint16_t increment_sfn_sf_by(uint16_t sfn_sf, uint8_t increment) return sfn_sf; } +int send_mac_slot_indications(vnf_p7_t* vnf_p7) +{ + nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections; + while(curr != 0) + { + if(curr->in_sync == 1) + { + // ask for subframes in the future + //uint16_t sfn_sf_adv = increment_sfn_sf_by(curr->sfn_sf, 2); + + //vnf_p7->_public.subframe_indication(&(vnf_p7->_public), curr->phy_id, sfn_sf_adv); + // suggestion fix by Haruki NAOI + //printf("\nsfn:%d, slot:%d\n",curr->sfn,curr->slot); + vnf_p7->_public.slot_indication(&(vnf_p7->_public), curr->phy_id, curr->sfn,curr->slot); + } + + curr = curr->next; + } + + return 0; +} int send_mac_subframe_indications(vnf_p7_t* vnf_p7) { @@ -392,7 +456,7 @@ int send_mac_subframe_indications(vnf_p7_t* vnf_p7) int vnf_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info, uint8_t* msg, const uint32_t len) { int sendto_result = sendto(vnf_p7->socket, msg, len, 0, (struct sockaddr*)&(p7_info->remote_addr), sizeof(p7_info->remote_addr)); - + //printf("\nSending p7 message sfn=%d,slot=%d\n",vnf_p7->p7_connections->sfn,vnf_p7->p7_connections->slot); if(sendto_result != len) { NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sendto_result %d %d\n", __FUNCTION__, sendto_result, errno); @@ -401,6 +465,100 @@ int vnf_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info, u return 0; } +int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header) +{ + + nfapi_vnf_p7_connection_info_t* p7_connection = vnf_p7_connection_info_list_find(vnf_p7, header->phy_id); + if(p7_connection) + { + int send_result = 0; + uint8_t buffer[1024 * 32]; + + header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, p7_connection->sequence_number); + + int len = nfapi_nr_p7_message_pack(header, buffer, sizeof(buffer), &vnf_p7->_public.codec_config); + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size); + + if(len < 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() failed to pack p7 message phy_id:%d\n", __FUNCTION__, header->phy_id); + return -1; + } + + if(len > vnf_p7->_public.segment_size) + { + // todo : consider replacing with the sendmmsg call + // todo : worry about blocking writes? + + // segmenting the transmit + int msg_body_len = len - NFAPI_P7_HEADER_LENGTH ; + int seg_body_len = vnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH ; + int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0); + + int segment = 0; + int offset = NFAPI_P7_HEADER_LENGTH; + uint8_t tx_buffer[vnf_p7->_public.segment_size]; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() MORE THAN ONE SEGMENT phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size); + for(segment = 0; segment < segment_count; ++segment) + { + uint8_t last = 0; + uint16_t size = vnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH; + if(segment + 1 == segment_count) + { + last = 1; + size = (msg_body_len) - (seg_body_len * segment); + } + + uint16_t segment_size = size + NFAPI_P7_HEADER_LENGTH; + + // Update the header with the m and segement + memcpy(&tx_buffer[0], buffer, NFAPI_P7_HEADER_LENGTH); + + // set the segment length + tx_buffer[4] = (segment_size & 0xFF00) >> 8; + tx_buffer[5] = (segment_size & 0xFF); + + // set the m & segment number + tx_buffer[6] = ((!last) << 7) + segment; + + memcpy(&tx_buffer[NFAPI_P7_HEADER_LENGTH], &buffer[0] + offset, size); + offset += size; + + if(vnf_p7->_public.checksum_enabled) + { + nfapi_p7_update_checksum(tx_buffer, segment_size); + } + + nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr)); + + send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &tx_buffer[0], segment_size); + } + } + else + { + if(vnf_p7->_public.checksum_enabled) + { + nfapi_p7_update_checksum(buffer, len); + } + + nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr)); + + // simple case that the message fits in a single segement + send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &buffer[0], len); + } + + p7_connection->sequence_number++; + + return send_result; + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find p7 connection info for phy_id:%d\n", __FUNCTION__, header->phy_id); + return -1; + } +} + int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header) { @@ -466,7 +624,7 @@ int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* hea nfapi_p7_update_checksum(tx_buffer, segment_size); } - nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn_sf, vnf_p7->sf_start_time_hr)); + nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr)); send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &tx_buffer[0], segment_size); } @@ -478,7 +636,7 @@ int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* hea nfapi_p7_update_checksum(buffer, len); } - nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn_sf, vnf_p7->sf_start_time_hr)); + nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr)); // simple case that the message fits in a single segement send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &buffer[0], len); @@ -494,7 +652,6 @@ int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* hea return -1; } } - int vnf_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info) { nfapi_dl_node_sync_t dl_node_sync; @@ -508,6 +665,52 @@ int vnf_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t return vnf_p7_pack_and_send_p7_msg(vnf_p7, &dl_node_sync.header); } +int vnf_nr_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info) +{ + + nfapi_nr_dl_node_sync_t dl_node_sync; + memset(&dl_node_sync, 0, sizeof(dl_node_sync)); + + dl_node_sync.header.phy_id = p7_info->phy_id; + dl_node_sync.header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC; + //dl_node_sync.t1 = calculate_t1(p7_info->sfn_sf, vnf_p7->sf_start_time_hr); + dl_node_sync.t1 = calculate_nr_t1(p7_info->sfn,p7_info->slot, vnf_p7->slot_start_time_hr); + dl_node_sync.delta_sfn_slot = 0; + + return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &dl_node_sync.header); +} + +int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info) +{ + + if(p7_info->in_sync == 1) + { + uint16_t dl_sync_period_mask = p7_info->dl_in_sync_period-1; + // uint16_t sfn_sf_dec = NFAPI_SFNSF2DEC(p7_info->sfn_sf); + uint16_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(p7_info->sfn,p7_info->slot); + + //if ((((sfn_sf_dec + p7_info->dl_in_sync_offset) % NFAPI_MAX_SFNSFDEC) & dl_sync_period_mask) == 0) + if ((((sfn_slot_dec + p7_info->dl_in_sync_offset) % NFAPI_MAX_SFNSLOTDEC) & dl_sync_period_mask) == 0) + { + vnf_nr_build_send_dl_node_sync(vnf_p7, p7_info); + } + } + else + { + uint16_t dl_sync_period_mask = p7_info->dl_out_sync_period-1; + //uint16_t sfn_sf_dec = NFAPI_SFNSF2DEC(p7_info->sfn_sf); + uint16_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(p7_info->sfn, p7_info->slot); + + //if ((((sfn_sf_dec + p7_info->dl_out_sync_offset) % NFAPI_MAX_SFNSFDEC) & dl_sync_period_mask) == 0) + if ((((sfn_slot_dec + p7_info->dl_out_sync_offset) % NFAPI_MAX_SFNSLOTDEC) & dl_sync_period_mask) == 0) + { + vnf_nr_build_send_dl_node_sync(vnf_p7, p7_info); + } + } + return 0; +} + + int vnf_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info) { @@ -1251,6 +1454,389 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) } } +void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + //printf("received UL Node sync"); + + uint32_t now_time_hr = vnf_get_current_time_hr(); + + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_ul_node_sync: NULL parameters\n"); + return; + } + + nfapi_nr_ul_node_sync_t ind; + if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_nr_ul_node_sync_t), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack ul_node_sync\n"); + return; + } + + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Received UL_NODE_SYNC phy_id:%d t1:%d t2:%d t3:%d\n", ind.header.phy_id, ind.t1, ind.t2, ind.t3); + + nfapi_vnf_p7_connection_info_t* phy = vnf_p7_connection_info_list_find(vnf_p7, ind.header.phy_id); + uint32_t t4 = calculate_nr_t4(now_time_hr, phy->sfn, phy->slot, vnf_p7->slot_start_time_hr); + + uint32_t tx_2_rx = t4>ind.t1 ? t4 - ind.t1 : t4 + NFAPI_MAX_SFNSLOTDEC - ind.t1 ; //time taken to receive ul node sync - time taken to send dl node sync + uint32_t pnf_proc_time = ind.t3 - ind.t2; + + // divide by 2 using shift operator + uint32_t latency = (tx_2_rx - pnf_proc_time) >> 1; + + if(!(phy->filtered_adjust)) + { + phy->latency[phy->min_sync_cycle_count] = latency; + + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) PNF to VNF !sync phy_id:%d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d\n", + // phy->sfn, phy->slot, ind.header.phy_id, ind.t1, ind.t2, ind.t3, t4, + // tx_2_rx, pnf_proc_time, latency); + } + else + { + phy->latency[phy->min_sync_cycle_count] = latency; + + //if(phy->min_sync_cycle_count != SYNC_CYCLE_COUNT) + { + if (ind.t2 < phy->previous_t2 && ind.t1 > phy->previous_t1) + { + // Only t2 wrap has occurred!!! + phy->slot_offset = (NFAPI_MAX_SFNSLOTDEC + ind.t2) - ind.t1 - latency; + } + else if (ind.t2 > phy->previous_t2 && ind.t1 < phy->previous_t1) + { + // Only t1 wrap has occurred + phy->slot_offset = ind.t2 - ( ind.t1 + NFAPI_MAX_SFNSLOTDEC) - latency; + } + else + { + // Either no wrap or both have wrapped + phy->slot_offset = ind.t2 - ind.t1 - latency; + } + + if (phy->slot_offset_filtered == 0) + { + phy->slot_offset_filtered = phy->slot_offset; + } + else + { + int32_t oldFilteredValueShifted = phy->slot_offset_filtered << 5; + int32_t newOffsetShifted = phy->slot_offset << 5; + + // 1/8 of new and 7/8 of old + phy->slot_offset_filtered = ((newOffsetShifted >> 3) + ((oldFilteredValueShifted * 7) >> 3)) >> 5; + } + } + + if(1) + { + 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", + // phy->sfn, phy->slot, 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->slot_offset, phy->slot_offset_filtered, + // (ind.t1previous_t1), (ind.t2previous_t2)); + } + + } + + if (phy->filtered_adjust && (phy->slot_offset_filtered > 1e6 || phy->slot_offset_filtered < -1e6)) + { + phy->filtered_adjust = 0; + phy->zero_count=0; + phy->min_sync_cycle_count = 2; + phy->in_sync = 0; + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s - ADJUST TOO BAD - go out of filtered phy->slot_offset_filtered:%d\n", __FUNCTION__, phy->slot_offset_filtered); + } + + if(phy->min_sync_cycle_count) + phy->min_sync_cycle_count--; + + if(phy->min_sync_cycle_count == 0) + { + uint32_t curr_sfn = phy->sfn; + uint32_t curr_slot = phy->slot; + int32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(phy->sfn,phy->slot); + + if(!phy->filtered_adjust) + { + int i = 0; + //phy->average_latency = 0; + for(i = 0; i < SYNC_CYCLE_COUNT; ++i) + { + phy->average_latency += phy->latency[i]; + + } + phy->average_latency /= SYNC_CYCLE_COUNT; + + phy->slot_offset = ind.t2 - (ind.t1 - phy->average_latency); + + sfn_slot_dec += (phy->slot_offset / 500); + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF slot offset:%d sfn :%d slot:%d \n",phy->slot_offset,NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec),NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec) ); + + + } + else + { + sfn_slot_dec += ((phy->slot_offset_filtered + 250) / 500); //Round up to go from microsecond to slot + + } + + if(sfn_slot_dec < 0) + { + sfn_slot_dec += NFAPI_MAX_SFNSLOTDEC; + } + else if( sfn_slot_dec >= NFAPI_MAX_SFNSLOTDEC) + { + sfn_slot_dec -= NFAPI_MAX_SFNSLOTDEC; + } + + + uint16_t new_sfn = NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec); + uint16_t new_slot = NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec); + + { + phy->adjustment = NFAPI_SFNSLOT2DEC(new_sfn, new_slot) - NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot); + + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF phy_id:%d adjustment%d phy->previous_slot_offset_filtered:%d phy->previous_slot_offset_filtered:%d phy->slot_offset_trend:%d\n", ind.header.phy_id, phy->adjustment, phy->previous_slot_offset_filtered, phy->previous_slot_offset_filtered, phy->slot_offset_trend); + + phy->previous_t1 = 0; + phy->previous_t2 = 0; + + if(phy->previous_slot_offset_filtered > 0) + { + if( phy->slot_offset_filtered > phy->previous_slot_offset_filtered) + { + // pnf is getting futher ahead of vnf + //phy->sf_offset_trend = phy->sf_offset_filtered - phy->previous_sf_offset_filtered; + phy->slot_offset_trend = (phy->slot_offset_filtered + phy->previous_slot_offset_filtered)/2; + } + else + { + // pnf is getting back in sync + } + } + else if(phy->previous_slot_offset_filtered < 0) + { + if(phy->slot_offset_filtered < phy->previous_slot_offset_filtered) + { + // vnf is getting future ahead of pnf + //phy->sf_offset_trend = -(phy->sf_offset_filtered - phy->previous_sf_offset_filtered); + phy->slot_offset_trend = (-(phy->slot_offset_filtered + phy->previous_slot_offset_filtered)) /2; + } + else + { + // vnf is getting back in sync + } + } + + + int insync_minor_adjustment_1 = phy->slot_offset_trend / 6; + int insync_minor_adjustment_2 = phy->slot_offset_trend / 2; + + + if(insync_minor_adjustment_1 == 0) + insync_minor_adjustment_1 = 2; + + if(insync_minor_adjustment_2 == 0) + insync_minor_adjustment_2 = 10; + + if(!phy->filtered_adjust) + { + if(phy->adjustment < 10) + { + phy->zero_count++; + + if(phy->zero_count >= 10) + { + phy->filtered_adjust = 1; + phy->zero_count = 0; + + NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF SFN/SF switching to filtered mode\n"); + } + } + else + { + phy->zero_count = 0; + } + } + else + { + // Fine level of adjustment + if (phy->adjustment == 0) + { + if (phy->zero_count >= 10) + { + if(phy->in_sync == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF P7 In Sync with phy (phy_id:%d)\n", phy->phy_id); + + if(vnf_p7->_public.sync_indication) + (vnf_p7->_public.sync_indication)(&(vnf_p7->_public), 1); + } + + phy->in_sync = 1; + } + else + { + phy->zero_count++; + } + + if(phy->in_sync) + { + // in sync + if(phy->slot_offset_filtered > 250) + { + // VNF is slow + phy->insync_minor_adjustment = insync_minor_adjustment_1; //25; + phy->insync_minor_adjustment_duration = ((phy->slot_offset_filtered) / insync_minor_adjustment_1); + } + else if(phy->slot_offset_filtered < -250) + { + // VNF is fast + phy->insync_minor_adjustment = -(insync_minor_adjustment_1); //25; + phy->insync_minor_adjustment_duration = (((phy->slot_offset_filtered) / -(insync_minor_adjustment_1))); + } + else + { + phy->insync_minor_adjustment = 0; + } + + if(phy->insync_minor_adjustment != 0) + { + // NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (slot_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adjustment:%d\n", + // phy->sfn, phy->slot, ind.header.phy_id, + // phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, + // phy->slot_offset_filtered, + // insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend, + // NFAPI_SFNSLOT2DEC(new_sfn, new_slot), + // NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot), + // phy->adjustment); + } + } + } + else + { + if (phy->in_sync) + { + if(phy->adjustment == 0) + { + } + else if(phy->adjustment > 0) + { + // VNF is slow + //if(phy->adjustment == 1) + { + // + if(phy->slot_offset_filtered > 250) + { + // VNF is slow + phy->insync_minor_adjustment = insync_minor_adjustment_2; + phy->insync_minor_adjustment_duration = 2 * ((phy->slot_offset_filtered - 250) / insync_minor_adjustment_2); + } + else if(phy->slot_offset_filtered < -250) + { + // VNF is fast + phy->insync_minor_adjustment = -(insync_minor_adjustment_2); + phy->insync_minor_adjustment_duration = 2 * ((phy->slot_offset_filtered + 250) / -(insync_minor_adjustment_2)); + } + + } + //else + { + // out of sync? + } + + // NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (adjustment:%d slot_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adj:%d\n", + // phy->sfn, phy->slot, ind.header.phy_id, + // phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->slot_offset_filtered, + // insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend, + // NFAPI_SFNSLOT2DEC(new_sfn, new_slot), + // NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot), + // phy->adjustment); + + } + else if(phy->adjustment < 0) + { + // VNF is fast + //if(phy->adjustment == -1) + { + // + if(phy->slot_offset_filtered > 250) + { + // VNF is slow + phy->insync_minor_adjustment = insync_minor_adjustment_2; + phy->insync_minor_adjustment_duration = 2 * ((phy->slot_offset_filtered - 250) / insync_minor_adjustment_2); + } + else if(phy->slot_offset_filtered < -250) + { + // VNF is fast + phy->insync_minor_adjustment = -(insync_minor_adjustment_2); + phy->insync_minor_adjustment_duration = 2 * ((phy->slot_offset_filtered + 250) / -(insync_minor_adjustment_2)); + } + } + //else + { + // out of sync? + } + + // NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (adjustment:%d slot_offset_filtered:%d) %d %d %d\n", + // phy->sfn, phy->slot, ind.header.phy_id, + // phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->slot_offset_filtered, + // insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend); + } + + /* + if (phy->adjustment > 10 || phy->adjustment < -10) + { + phy->zero_count++; // Add one to the getting out of sync counter + } + else + { + phy->zero_count = 0; // Small error - zero the out of sync counter + } + + if (phy->zero_count >= 10) // If we have had 10 consecutive large errors - drop out of sync + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "we have fallen out of sync...\n"); + //pP7SockInfo->syncAchieved = 0; + } + */ + } + } + } + + + if(phy->in_sync == 0) + { + /*NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n", + ind.header.phy_id, (phy->in_sync ? "via sfn" : "now"), + NFAPI_SFNSF2DEC(curr_sfn_sf), NFAPI_SFNSF2DEC(new_sfn_sf), phy->adjustment, + phy->filtered_adjust ? "FILTERED" : "ABSOLUTE", + phy->zero_count, + phy->in_sync ? "IN_SYNC" : "OUT_OF_SYNC");*/ + + phy->sfn = new_sfn; + phy->slot = new_slot; + } + } + + // reset for next cycle + phy->previous_slot_offset_filtered = phy->slot_offset_filtered; + phy->min_sync_cycle_count = 2; + phy->slot_offset_filtered = 0; + phy->slot_offset = 0; + } + else + { + phy->previous_t1 = ind.t1; + phy->previous_t2 = ind.t2; + } +} + void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) { if (pRecvMsg == NULL || vnf_p7 == NULL) @@ -1283,6 +1869,41 @@ void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) } } + +void vnf_nr_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + if (pRecvMsg == NULL || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_timing_info: NULL parameters\n"); + return; + } + + nfapi_nr_timing_info_t ind; + if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_timing_info_t), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack timing_info\n"); + return; + } + + if (vnf_p7 && vnf_p7->p7_connections) + { + //int16_t vnf_pnf_sfnsf_delta = NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf) - NFAPI_SFNSF2DEC(ind.last_sfn_sf); + int16_t vnf_pnf_sfnslot_delta = NFAPI_SFNSLOT2DEC(vnf_p7->p7_connections[0].sfn,vnf_p7->p7_connections[0].slot) - NFAPI_SFNSLOT2DEC(ind.last_sfn,ind.last_slot); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PNF:SFN/SF:%d VNF:SFN/SF:%d deltaSFNSF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind.last_sfn_sf), NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), vnf_pnf_sfnsf_delta); + + // Panos: Careful here!!! Modification of the original nfapi-code + //if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1) + //printf("VNF-PNF delta - %d", vnf_pnf_sfnslot_delta); + if (vnf_pnf_sfnslot_delta>0 || vnf_pnf_sfnslot_delta < 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnslot_delta,NFAPI_SFNSLOT2DEC(vnf_p7->p7_connections[0].sfn,vnf_p7->p7_connections[0].slot),NFAPI_SFNSLOT2DEC(ind.last_sfn,ind.last_slot)) ; + // Panos: Careful here!!! Modification of the original nfapi-code + // vnf_p7->p7_connections[0].sfn = ind.last_sfn; + // vnf_p7->p7_connections[0].slot = ind.last_slot; + } + } +} + void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) { nfapi_p7_message_header_t header; @@ -1378,6 +1999,101 @@ void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) } } +void vnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + nfapi_p7_message_header_t header; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); + return; + } + + // unpack the message header + if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + // ensure the message is sensible + if (recvMsgLen < 8 || pRecvMsg == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen); + return; + } + + switch (header.message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC: + vnf_nr_handle_ul_node_sync(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_TIMING_INFO: + vnf_nr_handle_timing_info(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_HARQ_INDICATION: + vnf_handle_harq_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_CRC_INDICATION: + vnf_handle_crc_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_RX_ULSCH_INDICATION: + vnf_handle_rx_ulsch_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_RACH_INDICATION: + vnf_handle_rach_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_SRS_INDICATION: + vnf_handle_srs_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_RX_SR_INDICATION: + vnf_handle_rx_sr_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_RX_CQI_INDICATION: + vnf_handle_rx_cqi_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_LBT_DL_INDICATION: + vnf_handle_lbt_dl_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_NB_HARQ_INDICATION: + vnf_handle_nb_harq_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_NRACH_INDICATION: + vnf_handle_nrach_indication(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_UE_RELEASE_RESPONSE: + vnf_handle_ue_release_resp(pRecvMsg, recvMsgLen, vnf_p7); + break; + + default: + { + if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && + header.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) + { + vnf_handle_p7_vendor_extension(pRecvMsg, recvMsgLen, vnf_p7, header.message_id); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Unknown message ID %d\n", header.message_id); + } + } + break; + } +} + void vnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) { nfapi_p7_message_header_t messageHeader; @@ -1496,6 +2212,200 @@ void vnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) } } +void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) +{ + nfapi_p7_message_header_t messageHeader; + + // validate the input params + if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p7_message: invalid input params (%d %d %d)\n", pRecvMsg, recvMsgLen, vnf_p7); + return; + } + + // unpack the message header + if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p7_message_header_t), &vnf_p7->_public.codec_config) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return; + } + + if(vnf_p7->_public.checksum_enabled) + { + uint32_t checksum = nfapi_p7_calculate_checksum(pRecvMsg, recvMsgLen); + if(checksum != messageHeader.checksum) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d msg:%d len:%d\n", checksum, messageHeader.checksum, messageHeader.message_id, recvMsgLen); + return; + } + } + + uint8_t m = NFAPI_P7_GET_MORE(messageHeader.m_segment_sequence); + uint8_t segment_num = NFAPI_P7_GET_SEGMENT(messageHeader.m_segment_sequence); + uint8_t sequence_num = NFAPI_P7_GET_SEQUENCE(messageHeader.m_segment_sequence); + + + if(m == 0 && segment_num == 0) + { + // we have a complete message + // ensure the message is sensible + if (recvMsgLen < 8 || pRecvMsg == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen); + return; + } + + //vnf_dispatch_p7_message(&messageHeader, pRecvMsg, recvMsgLen, vnf_p7); + vnf_nr_dispatch_p7_message(pRecvMsg, recvMsgLen, vnf_p7); + } + else + { + nfapi_vnf_p7_connection_info_t* phy = vnf_p7_connection_info_list_find(vnf_p7, messageHeader.phy_id); + + if(phy) + { + vnf_p7_rx_message_t* rx_msg = vnf_p7_rx_reassembly_queue_add_segment(vnf_p7, &(phy->reassembly_queue), sequence_num, segment_num, m, pRecvMsg, recvMsgLen); + + if(rx_msg->num_segments_received == rx_msg->num_segments_expected) + { + // send the buffer on + uint16_t i = 0; + uint16_t length = 0; + for(i = 0; i < rx_msg->num_segments_expected; ++i) + { + length += rx_msg->segments[i].length - (i > 0 ? NFAPI_P7_HEADER_LENGTH : 0); + } + + if(phy->reassembly_buffer_size < length) + { + vnf_p7_free(vnf_p7, phy->reassembly_buffer); + phy->reassembly_buffer = 0; + } + + if(phy->reassembly_buffer == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Resizing VNF_P7 Reassembly buffer %d->%d\n", phy->reassembly_buffer_size, length); + phy->reassembly_buffer = (uint8_t*)vnf_p7_malloc(vnf_p7, length); + + if(phy->reassembly_buffer == 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate VNF_P7 reassemby buffer len:%d\n", length); + return; + } + memset(phy->reassembly_buffer, 0, length); + phy->reassembly_buffer_size = length; + } + + uint16_t offset = 0; + for(i = 0; i < rx_msg->num_segments_expected; ++i) + { + if(i == 0) + { + memcpy(phy->reassembly_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length); + offset += rx_msg->segments[i].length; + } + else + { + memcpy(phy->reassembly_buffer + offset, rx_msg->segments[i].buffer + NFAPI_P7_HEADER_LENGTH, rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH); + offset += rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH; + } + } + + + //pnf_dispatch_p7_message(pnf_p7->reassemby_buffer, length, pnf_p7, rx_msg->rx_hr_time); + vnf_nr_dispatch_p7_message(phy->reassembly_buffer, length , vnf_p7); + + + // delete the structure + vnf_p7_rx_reassembly_queue_remove_msg(vnf_p7, &(phy->reassembly_queue), rx_msg); + } + + vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7, &(phy->reassembly_queue), 1000); + } + else + { + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Unknown phy id %d\n", messageHeader.phy_id); + } + } +} + +int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7) +{ + int recvfrom_result = 0; + struct sockaddr_in remote_addr; + socklen_t remote_addr_size = sizeof(remote_addr); + + do + { + // peek the header + uint8_t header_buffer[NFAPI_P7_HEADER_LENGTH]; + recvfrom_result = recvfrom(vnf_p7->socket, header_buffer, NFAPI_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size); + + if(recvfrom_result > 0) + { + // get the segment size + nfapi_p7_message_header_t header; + if(nfapi_p7_message_header_unpack(header_buffer, NFAPI_P7_HEADER_LENGTH, &header, sizeof(header), 0) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n"); + return -1; + } + + // resize the buffer if we have a large segment + if(header.message_length > vnf_p7->rx_message_buffer_size) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length); + vnf_p7->rx_message_buffer = realloc(vnf_p7->rx_message_buffer, header.message_length); + vnf_p7->rx_message_buffer_size = header.message_length; + } + + // read the segment + recvfrom_result = recvfrom(vnf_p7->socket, vnf_p7->rx_message_buffer, header.message_length, MSG_WAITALL, (struct sockaddr*)&remote_addr, &remote_addr_size); + + // todo : how to handle incomplete readfroms, need some sort of buffer/select + + if(recvfrom_result == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "recvfrom returned 0\n"); + } + else if(recvfrom_result != header.message_length) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "did not receive the entire message %d %d\n", recvfrom_result, header.message_length); + + recvfrom_result += recvfrom(vnf_p7->socket, &vnf_p7->rx_message_buffer[recvfrom_result], header.message_length - recvfrom_result, MSG_WAITALL, (struct sockaddr*)&remote_addr, &remote_addr_size); + + } + + + if(recvfrom_result > 0) + { + vnf_nr_handle_p7_message(vnf_p7->rx_message_buffer, recvfrom_result, vnf_p7); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "recvfrom failed %d %d\n", recvfrom_result, errno); + } + } + + if(recvfrom_result == -1) + { + if(errno == EAGAIN || errno == EWOULDBLOCK) + { + // return to the select + //NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom would block :%d\n", __FUNCTION__, errno); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom failed errno:%d\n", __FUNCTION__, errno); + } + } + } + while(recvfrom_result > 0); + + return 0; +} + int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7) { int recvfrom_result = 0; diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c index a0efeeb5f4..3fa1f035fd 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c @@ -28,6 +28,7 @@ #define FAPI2_IP_DSCP 0 + nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create() { vnf_p7_t* _this = (vnf_p7_t*)calloc(1, sizeof(vnf_p7_t)); @@ -90,6 +91,368 @@ struct timespec timespec_sub(struct timespec lhs, struct timespec rhs) // monitor the p7 endpoints and the timing loop and // send indications to mac +int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config) +{ + if(config == 0) + return -1; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + + // Create p7 receive udp port + // todo : this needs updating for Ipv6 + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port); + + // open the UDP socket + if ((vnf_p7->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno); + return -1; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 socket created...\n"); + + // configure the UDP socket options + int iptos_value = FAPI2_IP_DSCP << 2; + if (setsockopt(vnf_p7->socket, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (IP_TOS) errno: %d\n", errno); + return -1; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 setsockopt succeeded...\n"); + + // Create the address structure + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(config->port); + addr.sin_addr.s_addr = INADDR_ANY; + + // bind to the configured port + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 binding too %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + if (bind(vnf_p7->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) + //if (sctp_bindx(config->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), 0) < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno); + return -1; + } + + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 bind succeeded...\n"); + + + //struct timespec original_pselect_timeout; + struct timespec pselect_timeout; + pselect_timeout.tv_sec = 0; + pselect_timeout.tv_nsec = 500000; // ns in a 0.5 ms + //pselect_timeout.tv_nsec = 500000; + + struct timespec pselect_start; + struct timespec pselect_stop; + + //struct timespec sf_end; + + long last_millisecond = -1; + + +// struct timespec sf_duration; //Change to slot_duration? +// sf_duration.tv_sec = 0; +// sf_duration.tv_nsec = 0.5e6; // We want 1ms pause //We want 0.5 ms pause for NR + struct timespec slot_duration; + slot_duration.tv_sec = 0; + //slot_duration.tv_nsec = 0.5e6; + slot_duration.tv_nsec = 0.5e6; + + +// struct timespec sf_start; //Change to slot_start? + struct timespec slot_start; +// clock_gettime(CLOCK_MONOTONIC, &sf_start); + clock_gettime(CLOCK_MONOTONIC, &slot_start); + long millisecond = slot_start.tv_nsec / 1e6; //Check if we have to change + //long millisecond = slot_start.tv_nsec / 0.5e6; +// sf_start = timespec_add(sf_start, sf_duration); + slot_start = timespec_add(slot_start, slot_duration); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "next slot will start at %d.%d\n", slot_start.tv_sec, slot_start.tv_nsec); + + while(vnf_p7->terminate == 0) + { + fd_set rfds; + int maxSock = 0; + FD_ZERO(&rfds); + int selectRetval = 0; + + // Add the p7 socket + FD_SET(vnf_p7->socket, &rfds); + maxSock = vnf_p7->socket; + + clock_gettime(CLOCK_MONOTONIC, &pselect_start); + //long millisecond = pselect_start.tv_nsec / 1e6; + + if((last_millisecond == -1) || (millisecond == last_millisecond) || (millisecond == (last_millisecond + 1) % 1000) ) + { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "pselect_start:%d.%d sf_start:%d.%d\n", pselect_start.tv_sec, pselect_start.tv_nsec, sf_start.tv_sec, sf_start.tv_nsec); + + + //if((pselect_start.tv_sec > sf_start.tv_sec) || + // ((pselect_start.tv_sec == sf_start.tv_sec) && (pselect_start.tv_nsec > sf_start.tv_nsec))) + if((pselect_start.tv_sec > slot_start.tv_sec) || ((pselect_start.tv_sec == slot_start.tv_sec) && (pselect_start.tv_nsec > slot_start.tv_nsec))) + { + // overran the end of the subframe we do not want to wait + pselect_timeout.tv_sec = 0; + pselect_timeout.tv_nsec = 0; + + //struct timespec overrun = timespec_sub(pselect_start, sf_start); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Subframe overrun detected of %d.%d running to catchup\n", overrun.tv_sec, overrun.tv_nsec); + } + else + { + // still time before the end of the subframe wait + //pselect_timeout = timespec_sub(sf_start, pselect_start); + pselect_timeout = timespec_sub(slot_start, pselect_start); + } + +//original_pselect_timeout = pselect_timeout; + + // detemine how long to sleep in ns before the start of the next 1ms + //pselect_timeout.tv_nsec = 1e6 - (pselect_start.tv_nsec % 1000000); + + //uint8_t underrun_possible =0; + + // if we are not sleeping until the next milisecond due to the + // insycn minor adjment flag it so we don't consider it an error + //uint8_t underrun_possible =0; + /* + { + nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections; + if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0 && pselect_start.tv_nsec != 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] Subframe minor adjustment %d (%d->%d)\n", phy->insync_minor_adjustment, + pselect_timeout.tv_nsec, pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000)) + if(phy->insync_minor_adjustment > 0) + { + // todo check we don't go below 0 + if((phy->insync_minor_adjustment * 1000) > pselect_timeout.tv_nsec) + pselect_timeout.tv_nsec = 0; + else + pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000); + + + //underrun_possible = 1; + } + else if(phy->insync_minor_adjustment < 0) + { + // todo check we don't go below 0 + pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000); + + + //phy->insync_minor_adjustment = 0; + phy->insync_minor_adjustment_duration--; + } + } + */ + + +//long wraps = pselect_timeout.tv_nsec % 1e9; + + + selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL); + // selectRetval = pselect(120, &rfds, NULL, NULL, &pselect_timeout, NULL); + + clock_gettime(CLOCK_MONOTONIC, &pselect_stop); + + nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections; + +if (selectRetval==-1 && errno == 22) +{ +// NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n", +// pselect_timeout.tv_sec, pselect_timeout.tv_nsec, +// phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment, +// sf_duration.tv_sec, sf_duration.tv_nsec); + +NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n", + pselect_timeout.tv_sec, pselect_timeout.tv_nsec, + phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment, + slot_duration.tv_sec, slot_duration.tv_nsec); + +} + if(selectRetval == 0) + { + // calculate the start of the next slot + //sf_start = timespec_add(sf_start, sf_duration); + slot_start = timespec_add(slot_start, slot_duration); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec); + + if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0) + { + long insync_minor_adjustment_ns = (phy->insync_minor_adjustment * 1000); + + //sf_start.tv_nsec -= insync_minor_adjustment_ns; + slot_start.tv_nsec -= insync_minor_adjustment_ns; + +#if 1 +/* if (sf_start.tv_nsec > 1e9) //Change to 0.5e6? + { + sf_start.tv_sec++; + sf_start.tv_nsec-=1e9; + } + else if (sf_start.tv_nsec < 0) + { + sf_start.tv_sec--; + sf_start.tv_nsec+=1e9; + }*/ + if (slot_start.tv_nsec > 1e9) + { + slot_start.tv_sec++; + slot_start.tv_nsec-=1e9; + } + else if (slot_start.tv_nsec < 0) + { + slot_start.tv_sec--; + slot_start.tv_nsec+=1e9; + } +#else + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] BEFORE adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d\n", phy->insync_minor_adjustment, sf_start.tv_nsec); + if(phy->insync_minor_adjustment > 0) + { + // decrease the subframe duration a little + if (sf_start.tv_nsec > insync_minor_adjustment_ns) + sf_start.tv_nsec -= insync_minor_adjustment_ns; + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] Adjustment would make it negative sf:%d.%ld adjust:%ld\n\n\n", sf_start.tv_sec, sf_start.tv_nsec, insync_minor_adjustment_ns); + sf_start.tv_sec--; + sf_start.tv_nsec += 1e9 - insync_minor_adjustment_ns; + } + } + else if(phy->insync_minor_adjustment < 0) + { + // todo check we don't go below 0 + // increase the subframe duration a little + sf_start.tv_nsec += insync_minor_adjustment_ns; + + if (sf_start.tv_nsec < 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] OVERFLOW %d.%ld\n\n\n\n", sf_start.tv_sec, sf_start.tv_nsec); + sf_start.tv_sec++; + sf_start.tv_nsec += 1e9; + } + } +#endif + + //phy->insync_minor_adjustment = 0; + phy->insync_minor_adjustment_duration--; + +// NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d duration:%u\n", +// phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration); + // NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Slot minor adjustment %dus slot_start.tv_nsec:%d duration:%u\n", + // phy->insync_minor_adjustment, slot_start.tv_nsec, phy->insync_minor_adjustment_duration); + + if (phy->insync_minor_adjustment_duration==0) + { + phy->insync_minor_adjustment = 0; + } + } + /* + long pselect_stop_millisecond = pselect_stop.tv_nsec / 1e6; + if(millisecond == pselect_stop_millisecond) + { + // we have woke up in the same subframe + if(underrun_possible == 0) + NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect underrun %ld (%d.%d)\n", millisecond, pselect_stop.tv_sec, pselect_stop.tv_nsec); + } + else if(((millisecond + 1) % 1000) != pselect_stop_millisecond) + { + // we have overrun the subframe + NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect overrun %ld %ld\n", millisecond, pselect_stop_millisecond); + NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe underrun %ld\n", millisecond); + } + last_millisecond = millisecond; + */ + + //millisecond ++; + millisecond = millisecond + 1; + + } + } + else + { + // we have overrun the subframe advance to go and collect $200 + + if((millisecond - last_millisecond) > 3) + NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe overrun %ld %ld (%ld)\n", millisecond, last_millisecond, millisecond - last_millisecond + 1); + + last_millisecond = ( last_millisecond + 1 ) % 1000; + selectRetval = 0; + } + + if(selectRetval == 0) + { + //vnf_p7->sf_start_time_hr = vnf_get_current_time_hr(); + vnf_p7->slot_start_time_hr = vnf_get_current_time_hr(); +struct timespec current_time; + clock_gettime(CLOCK_MONOTONIC, ¤t_time); + // pselect timed out + nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections; + while(curr != 0) + { + if (curr->slot == 19) + { //curr->slot = 0; + if(curr->sfn == 1023) + curr->sfn=0; + else + curr->sfn++; + curr->slot=0; + } + else + { + curr->slot++; + } + vnf_nr_sync(vnf_p7, curr); + curr = curr->next; + } + send_mac_slot_indications(vnf_p7); + } + else if(selectRetval > 0) + { + // have a p7 message + if(FD_ISSET(vnf_p7->socket, &rfds)) + { + vnf_nr_p7_read_dispatch_message(vnf_p7); + } + } + else + { + // pselect error + if(selectRetval == -1 && errno == EINTR) + { + // a sigal was received. + } + else + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d orginal:%d.%d last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond); + // should we exit now? + if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration + { + usleep(100000); + } + } + } + + } + + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n"); + close(vnf_p7->socket); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__); + + return 0; +} + + int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) { if(config == 0) @@ -408,6 +771,7 @@ if (selectRetval==-1 && errno == 22) return 0; } + int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config) { if(config == 0) @@ -434,17 +798,18 @@ int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr, memset(node, 0, sizeof(nfapi_vnf_p7_connection_info_t)); node->phy_id = phy_id; node->in_sync = 0; - node->dl_out_sync_offset = 30; + node->dl_out_sync_offset = 30;//TODO: Values need to be changed for NR,How to set the values node->dl_out_sync_period = 10; node->dl_in_sync_offset = 30; node->dl_in_sync_period = 512; - node->sfn_sf = 0; - + //node->sfn_sf = 0; + node->sfn = 0; + node->slot = 0; node->min_sync_cycle_count = 8; // save the remote endpoint information node->remote_addr.sin_family = AF_INET; - node->remote_addr.sin_port = htons(pnf_p7_port); + node->remote_addr.sin_port = pnf_p7_port;//htons(pnf_p7_port); node->remote_addr.sin_addr.s_addr = inet_addr(pnf_p7_addr); vnf_p7_connection_info_list_add(vnf_p7, node); @@ -490,7 +855,16 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti return -1; vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; - return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); + return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header); +} + +int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header); } int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req) @@ -501,6 +875,14 @@ int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_re vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); } +int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header); +} int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req) { if(config == 0 || req == 0) @@ -509,6 +891,14 @@ int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_reques vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); } +int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req) +{ + if(config == 0 || req == 0) + return -1; + + vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; + return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header); +} int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req) { if(config == 0 || req == 0) diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index b42ac6e4c8..e16c909835 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -144,7 +144,7 @@ int test_ldpc(short No_iteration, t_nrLDPC_procBuf nrLDPC_procBuf; t_nrLDPC_procBuf* p_nrLDPC_procBuf = &nrLDPC_procBuf; - t_nrLDPC_time_stats decoder_profiler; + t_nrLDPC_time_stats decoder_profiler = {0}; t_nrLDPC_time_stats* p_decoder_profiler =&decoder_profiler ; int32_t n_iter = 0; diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index bd6b944fef..e05045d3ed 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -20,6 +20,7 @@ */ #include "executables/nr-softmodem-common.h" +#include "common/utils/nr/nr_common.h" #include "PHY/defs_gNB.h" #include "PHY/phy_extern.h" #include "PHY/NR_REFSIG/nr_refsig.h" @@ -45,10 +46,42 @@ #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" -/* -extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn); -extern openair0_config_t openair0_cfg[MAX_CARDS]; -*/ +static +uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex) +{ + const uint64_t dl_freq_khz = downlink_frequency / 1000; + const int32_t delta_duplex_khz = delta_duplex / 1000; + + uint64_t center_freq_diff_khz = 999999999999999999; // 2^64 + uint16_t current_band = 0; + + for (int ind = 0; ind < nr_bandtable_size; ind++) { + + LOG_D(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min, nr_bandtable[ind].ul_min); + + if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max) + continue; + + int32_t current_offset_khz = nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min; + + if (current_offset_khz != delta_duplex_khz) + continue; + + uint64_t 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; + center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz); + } + } + + LOG_I(PHY, "DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n", + downlink_frequency, current_band, downlink_frequency+delta_duplex); + + AssertFatal(current_band != 0, "Can't find EUTRA band for frequency %"PRIu64" and duplex_spacing %u\n", downlink_frequency, delta_duplex); + + return current_band; +} int l1_north_init_gNB() { @@ -109,6 +142,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n"); + gNB->bad_pucch = 0; + 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); @@ -198,13 +233,15 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, common_vars->rxdata = (int32_t **)malloc16(Prx*sizeof(int32_t*)); common_vars->txdataF = (int32_t **)malloc16(Ptx*sizeof(int32_t*)); common_vars->rxdataF = (int32_t **)malloc16(Prx*sizeof(int32_t*)); + common_vars->beam_id = (uint8_t **)malloc16(Ptx*sizeof(uint8_t*)); for (i=0;itxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n", i,common_vars->txdataF[i], fp->samples_per_frame_wCP*sizeof(int32_t)); - + common_vars->beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t)); + memset(common_vars->beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame); } for (i=0;irxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); @@ -381,6 +418,13 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) } + +//Adding nr_schedule_handler +void install_nr_schedule_handlers(NR_IF_Module_t *if_inst) +{ + if_inst->NR_PHY_config_req = nr_phy_config_request; + if_inst->NR_Schedule_response = nr_schedule_response; +} /* void install_schedule_handlers(IF_Module_t *if_inst) { @@ -424,8 +468,8 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, gNB->mac_enabled = 1; 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->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); + fp->ul_CarrierFreq = 3600000000;//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) { @@ -434,7 +478,8 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, fp->nr_band = 261; // fp->threequarter_fs= 0; } - + + 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); @@ -448,7 +493,6 @@ 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; memcpy((void*)gNB_config,phy_config->cfg,sizeof(*phy_config->cfg)); RC.gNB[Mod_id]->mac_enabled = 1; @@ -459,13 +503,9 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { 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 ; - fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + int32_t dlul_offset = fp->ul_CarrierFreq - fp->dl_CarrierFreq; + fp->nr_band = get_band(fp->dl_CarrierFreq, dlul_offset); - 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; @@ -494,11 +534,12 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { // } RC.gNB[Mod_id]->configured = 1; - init_symbol_rotation(fp,fp->dl_CarrierFreq); + init_symbol_rotation(fp); LOG_I(PHY,"gNB %d configured\n",Mod_id); } + void init_nr_transport(PHY_VARS_gNB *gNB) { int i; int j; diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 648b820f07..2bd7d90620 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -125,7 +125,7 @@ int nr_phy_init_RU(RU_t *ru) { int beam_count = 0; if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1 for (p=0;pnb_log_antennas;p++) { - if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0 + //if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0 beam_count++; } AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx)); @@ -133,19 +133,25 @@ int nr_phy_init_RU(RU_t *ru) { int l_ind = 0; for (i=0; inb_log_antennas;p++) { - if ((fp->L_ssb >> (63-p)) & 0x01) { + //if ((fp->L_ssb >> (63-p)) & 0x01) { ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); for (j=0; jnb_tx; j++) { ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); for (re=0; reofdm_symbol_size; re++) - ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind]; + ru->beam_weights[i][p][j][re] = ru->bw_list[j][l_ind]; //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j); l_ind++; } // for j - } // for p - } + //} + } // for p } //for i } + + ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*)); + for(i=0; i< ru->nb_tx; ++i) { + ru->common.beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t)); + memset(ru->common.beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame); + } } // !=IF5 ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP ); diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 8bcc58160f..855acc01ff 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -71,33 +71,39 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, pdsch->llr128 = (int16_t **)malloc16_clear( sizeof(int16_t *) ); // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there - pdsch->rxdataF_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->rxdataF_ext = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->rho = (int32_t ***)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t **) ); + pdsch->dl_ch_estimates = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); //pdsch->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); //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 *) ); + pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_magr0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->ptrs_phase_per_slot = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->ptrs_re_per_slot = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); // the allocated memory size is fixed: - AssertFatal( fp->nb_antennas_rx <= 2, "nb_antennas_rx > 2" ); + AssertFatal( fp->nb_antennas_rx <= 4, "nb_antennas_rx > 4" );//Extend the max number of UE Rx antennas to 4 + const size_t num = 7*2*fp->N_RB_DL*12; for (int i=0; inb_antennas_rx; i++) { - pdsch->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); + pdsch->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + pdsch->rxdataF_uespec_pilots[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); + pdsch->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 ); + pdsch->ptrs_re_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14); + pdsch->dl_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * num); + pdsch->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t *) ); - for (int j=0; j<4; j++) { //fp->nb_antennas_tx; j++) - const int idx = (j<<1)+i; - const size_t num = 7*2*fp->N_RB_DL*12; - pdsch->rxdataF_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - pdsch->rxdataF_uespec_pilots[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); + for (int j=0; jnb_antennas_rx)+i; + for (int k=0; krho[i][j*NR_MAX_NB_LAYERS+k] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + } pdsch->rxdataF_comp0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2); pdsch->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); @@ -108,9 +114,6 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, 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); } } } @@ -139,16 +142,14 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig int n_scid; abstraction_flag = 0; - fp->nb_antennas_tx = 1; - 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; 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); + //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_gNB_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[gNB_id]" ); - AssertFatal(nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" ); + AssertFatal( fp->nb_antennas_rx <= 4, "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++) { @@ -276,7 +277,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, } } - //PDCCH DMRS init (eNB offset = 0) + //PDCCH DMRS init (gNB 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"); @@ -291,6 +292,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, } } + ue->scramblingID_pdcch = fp->Nid_cell; + nr_gold_pdcch(ue,fp->Nid_cell); + //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]; @@ -310,6 +314,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, } } + // initializing the scrambling IDs for PDSCH DMRS + for (int i=0; i<2; i++) + ue->scramblingID[i]=fp->Nid_cell; + + nr_gold_pdsch(ue,ue->scramblingID); + // DLSCH for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { for (th_id=0; th_idpdsch_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 *)); + 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 *) ); } - for (int i=0; inb_antennas_rx; i++) { - for (th_id=0; th_idpdsch_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][gNB_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( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); } for (i=0; inb_antennas_rx; i++) for (j=0; j<4; j++) { - const int idx = (j<<1)+i; + const int idx = (j*fp->nb_antennas_rx)+i; const size_t num = 7*2*fp->N_RB_DL*12+4; for (th_id=0; th_idpdsch_vars[th_id][gNB_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 ); } } @@ -361,15 +365,15 @@ 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][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 *)); + ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); } for (int i=0; inb_antennas_rx; i++) for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) - const int idx = (j<<1)+i; + const int idx = (j*fp->nb_antennas_rx)+i; for (th_id=0; th_idpdsch_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)); @@ -383,26 +387,26 @@ 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][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 *)); + 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( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*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( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); // Channel estimates - 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 *)); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *)); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(4*fp->nb_antennas_rx*sizeof(int32_t *)); for (i=0; inb_antennas_rx; i++) { 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][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); + int idx = (j*fp->nb_antennas_rx)+i; + 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][gNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num); @@ -414,24 +418,24 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, } // PBCH - 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))); + 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( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pbch_vars[gNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pbch_vars[gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) ); + pbch_vars[gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*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[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[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); + int idx = (j*fp->nb_antennas_rx)+i; + 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 ); } } } @@ -507,50 +511,36 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue){ 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; + + double factor = 1.0; 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"); + factor = fp->samples_per_subframe / 30720.0; 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 + factor = fp->samples_per_subframe / 30720.0; 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"); + factor = fp->samples_per_subframe / 61440.0; 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); + AssertFatal(N_TA_offset == 431, "scs_common 240kHz only for FR2\n"); + factor = fp->samples_per_subframe / 61440.0; 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; + default: + AssertFatal(1==0, "Invalid scs_common!\n"); } - 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); + LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d, mu %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, fp->N_RB_DL, fp->numerology_index); } } diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index ba4147e5cd..34938501e3 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -27,12 +27,9 @@ 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) -{ +int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb) { int mu = fp->numerology_index; - uint8_t half_frame_index = fp->half_frame_bit; - uint8_t i_ssb = fp->ssb_index; int symbol = 0; uint8_t n, n_temp; nr_ssb_type_e type = fp->ssb_type; @@ -69,15 +66,11 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp) AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu); } - if (half_frame_index) - symbol += (5 * fp->symbols_per_slot * fp->slots_per_subframe); - return symbol; } -void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) +void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL) { - switch(mu) { case NR_MU_0: //15kHz scs @@ -99,108 +92,17 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) else AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu); } - - switch(bw){ - case 5: - case 15: - case 20: - case 25: - case 30: - case 40: //40 MHz - if (fp->threequarter_fs) { - fp->ofdm_symbol_size = 1536; - fp->first_carrier_offset = 900; //1536 - ( (106*12) / 2 ) - fp->nb_prefix_samples0 = 132; - fp->nb_prefix_samples = 108; - } - else { - fp->ofdm_symbol_size = 2048; - fp->first_carrier_offset = 1412; //2048 - ( (106*12) / 2 ) - fp->nb_prefix_samples0 = 176; - fp->nb_prefix_samples = 144; - } - break; - - case 50: - case 60: - case 70: - - case 80: //80 MHz - if (fp->threequarter_fs) { - fp->ofdm_symbol_size = 3072; - fp->first_carrier_offset = 1770; //3072 - ( (217*12) / 2 ) - fp->nb_prefix_samples0 = 264; - fp->nb_prefix_samples = 216; - } - else { - fp->ofdm_symbol_size = 4096; - fp->first_carrier_offset = 2794; //4096 - ( (217*12) / 2 ) - fp->nb_prefix_samples0 = 352; - fp->nb_prefix_samples = 288; - } - break; - - case 90: - AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu); - fp->ofdm_symbol_size = 4096; - fp->first_carrier_offset = 2626; //4096 - ( (245*12) / 2 ) - fp->nb_prefix_samples0 = 352; - fp->nb_prefix_samples = 288; - break; - case 100: - AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu); - fp->ofdm_symbol_size = 4096; - fp->first_carrier_offset = 2458; //4096 - ( (273*12) / 2 ) - fp->nb_prefix_samples0 = 352; - fp->nb_prefix_samples = 288; - break; - default: - AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp); - } break; case NR_MU_2: //60kHz scs fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2]; - - switch(bw){ //FR1 bands only - case 10: - case 15: - case 20: - case 25: - case 30: - case 40: - case 50: - case 60: - case 70: - case 80: - case 90: - case 100: - default: - AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp); - } break; case NR_MU_3: fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3]; fp->ssb_type = nr_ssb_type_D; - switch(bw){ - case 100: - fp->ofdm_symbol_size = 1024; - fp->first_carrier_offset = 628; //1024 - ( (66*12) / 2 ) - fp->nb_prefix_samples0 = 136; - fp->nb_prefix_samples = 72; - break; - case 50: - fp->ofdm_symbol_size = 512; - fp->first_carrier_offset = 320; //1024 - ( (66*12) / 2 ) - fp->nb_prefix_samples0 = 68; - fp->nb_prefix_samples = 36; - break; - default: - AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp); - } break; case NR_MU_4: @@ -209,9 +111,21 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) fp->ssb_type = nr_ssb_type_E; break; - default: - AssertFatal(1==0,"Invalid numerology index %d", mu); + default: + AssertFatal(1==0,"Invalid numerology index %d", mu); } + + if(fp->threequarter_fs) + fp->ofdm_symbol_size = 3 * 128; + else + fp->ofdm_symbol_size = 4 * 128; + + while(fp->ofdm_symbol_size < N_RB_DL * 12) + fp->ofdm_symbol_size <<= 1; + + fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2); + fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9; + fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu)); } uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp) @@ -280,13 +194,13 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, fp->half_frame_bit = 0; // half frame bit initialized to 0 here fp->numerology_index = mu; - set_scs_parameters(fp, mu, cfg->carrier_config.dl_bandwidth.value); + set_scs_parameters(fp, mu, fp->N_RB_DL); fp->slots_per_frame = 10* fp->slots_per_subframe; - fp->nb_antenna_ports_gNB = cfg->carrier_config.num_tx_ant.value;// It corresponds to pdsch_AntennaPorts + fp->nb_antenna_ports_gNB = 1; // It corresponds to the number of common antenna ports 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->nb_antennas_tx = cfg->carrier_config.num_tx_ant.value; // It corresponds to pdsch_AntennaPorts 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; @@ -334,6 +248,11 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, uint8_t Nid_cell = 0; int Ncp = NORMAL; + if(fp->nb_antennas_rx == 0) + fp->nb_antennas_rx = 1; + if(fp->nb_antennas_tx == 0) + fp->nb_antennas_tx = 1; + // default values until overwritten by RRCConnectionReconfiguration fp->nb_antenna_ports_gNB = nb_ant_ports_gNB; fp->tdd_config = tdd_cfg; @@ -352,9 +271,8 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->N_RB_UL = config->carrier_config.ul_grid_size[fp->numerology_index]; 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); + fp->frame_type = get_frame_type(fp->nr_band, fp->numerology_index); + int32_t uplink_frequency_offset = get_delta_duplex(fp->nr_band, fp->numerology_index); uplink_frequency_offset *= 1000; 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); @@ -374,7 +292,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->Ncp = Ncp; - set_scs_parameters(fp,fp->numerology_index,config->carrier_config.dl_bandwidth); + set_scs_parameters(fp, fp->numerology_index, fp->N_RB_DL); fp->slots_per_frame = 10* fp->slots_per_subframe; fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index 9c474264c8..2db0ccc258 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -392,7 +392,7 @@ void phy_config_update_sib13_request(PHY_Config_t *phy_config); int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); -int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp); +int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb); int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, 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); diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index b1f419b172..4405c46abf 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -145,7 +145,8 @@ int nr_beam_precoding(int32_t **txdataF, int slot, int symbol, int aa, - int nb_antenna_ports) + int nb_antenna_ports, + int offset) { @@ -155,14 +156,14 @@ int nr_beam_precoding(int32_t **txdataF, memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size)); for (p=0; pL_ssb >> (63-p)) & 0x01) { - multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size], + //if ((frame_parms->L_ssb >> (63-p)) & 0x01) { + multadd_cpx_vector((int16_t*)&txdataF[p][(symbol*frame_parms->ofdm_symbol_size)+offset], (int16_t*)beam_weights[p][aa], (int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], 0, frame_parms->ofdm_symbol_size, 15); - } + //} } return 0; } diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h index 72a1334fe9..20fdaa7ad8 100644 --- a/openair1/PHY/MODULATION/modulation_UE.h +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -51,16 +51,13 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue, int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, unsigned char l, - unsigned char Ns, - int sample_offset, - int no_prefix); + unsigned char Ns); 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, - int no_prefix); + int sample_offset); int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue, unsigned char l, diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 0a7088ba39..e32f6bf575 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -22,6 +22,101 @@ #include "nr_modulation.h" #include "PHY/NR_REFSIG/nr_mod_table.h" +//Table 6.3.1.5-1 Precoding Matrix W 1 layer 2 antenna ports 'n' = -1 and 'o' = -j +char nr_W_1l_2p[6][2][1] = { + {{'1'}, {'0'}},//pmi 0 + {{'0'}, {'1'}}, + {{'1'}, {'1'}}, + {{'1'}, {'n'}}, + {{'1'}, {'j'}}, + {{'1'}, {'o'}}//pmi 5 +}; + +//Table 6.3.1.5-3 Precoding Matrix W 1 layer 4 antenna ports 'n' = -1 and 'o' = -j +char nr_W_1l_4p[28][4][1] = { + {{'1'}, {'0'}, {'0'}, {'0'}},//pmi 0 + {{'0'}, {'1'}, {'0'}, {'0'}}, + {{'0'}, {'0'}, {'1'}, {'0'}}, + {{'0'}, {'0'}, {'0'}, {'1'}}, + {{'1'}, {'0'}, {'1'}, {'0'}}, + {{'1'}, {'0'}, {'n'}, {'0'}}, + {{'1'}, {'0'}, {'j'}, {'0'}}, + {{'1'}, {'0'}, {'o'}, {'0'}},//pmi 7 + {{'0'}, {'1'}, {'0'}, {'1'}},//pmi 8 + {{'0'}, {'1'}, {'0'}, {'n'}}, + {{'0'}, {'1'}, {'0'}, {'j'}}, + {{'0'}, {'1'}, {'0'}, {'o'}}, + {{'1'}, {'1'}, {'1'}, {'1'}}, + {{'1'}, {'1'}, {'j'}, {'j'}}, + {{'1'}, {'1'}, {'n'}, {'n'}}, + {{'1'}, {'1'}, {'o'}, {'o'}}, + {{'1'}, {'j'}, {'1'}, {'j'}},//pmi 16 + {{'1'}, {'j'}, {'j'}, {'n'}}, + {{'1'}, {'j'}, {'n'}, {'o'}}, + {{'1'}, {'j'}, {'o'}, {'1'}}, + {{'1'}, {'n'}, {'1'}, {'n'}}, + {{'1'}, {'n'}, {'j'}, {'o'}}, + {{'1'}, {'n'}, {'n'}, {'1'}}, + {{'1'}, {'n'}, {'o'}, {'j'}},//pmi 23 + {{'1'}, {'o'}, {'1'}, {'o'}},//pmi 24 + {{'1'}, {'o'}, {'j'}, {'1'}}, + {{'1'}, {'o'}, {'n'}, {'j'}}, + {{'1'}, {'o'}, {'o'}, {'n'}}//pmi 27 +}; + +//Table 6.3.1.5-4 Precoding Matrix W 2 antenna ports layers 2 'n' = -1 and 'o' = -j +char nr_W_2l_2p[3][2][2] = { + {{'1', '0'}, {'0', '1'}},//pmi 0 + {{'1', '1'}, {'1', 'n'}}, + {{'1', '1'}, {'j', 'o'}} //pmi 2 +}; + +//Table 6.3.1.5-5 Precoding Matrix W 2 layers 4 antenna ports 'n' = -1 and 'o' = -j +char nr_W_2l_4p[22][4][2] = { + {{'1', '0'}, {'0', '1'}, {'0', '0'}, {'0', '0'}},//pmi 0 + {{'1', '0'}, {'0', '0'}, {'0', '1'}, {'0', '0'}}, + {{'1', '0'}, {'0', '0'}, {'0', '0'}, {'0', '1'}}, + {{'0', '0'}, {'1', '0'}, {'0', '1'}, {'0', '0'}},//pmi 3 + {{'0', '0'}, {'1', '0'}, {'0', '0'}, {'0', '1'}},//pmi 4 + {{'0', '0'}, {'0', '0'}, {'1', '0'}, {'0', '1'}}, + {{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'o'}}, + {{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'j'}}, + {{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', '1'}},//pmi 8 + {{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', 'n'}}, + {{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'o'}}, + {{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'j'}},//pmi 11 + {{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', '1'}},//pmi 12 + {{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', 'n'}}, + {{'1', '1'}, {'1', '1'}, {'1', 'n'}, {'1', 'n'}}, + {{'1', '1'}, {'1', '1'}, {'j', 'o'}, {'j', 'o'}},//pmi 15 + {{'1', '1'}, {'j', 'j'}, {'1', 'n'}, {'j', 'o'}},//pmi 16 + {{'1', '1'}, {'j', 'j'}, {'j', 'o'}, {'n', '1'}}, + {{'1', '1'}, {'n', 'n'}, {'1', 'n'}, {'n', '1'}}, + {{'1', '1'}, {'n', 'n'}, {'j', 'o'}, {'o', 'j'}},//pmi 19 + {{'1', '1'}, {'o', 'o'}, {'1', 'n'}, {'o', 'j'}}, + {{'1', '1'}, {'o', 'o'}, {'j', 'o'}, {'1', 'n'}}//pmi 21 +}; + +//Table 6.3.1.5-6 Precoding Matrix W 3 layers 4 antenna ports 'n' = -1 and 'o' = -j +char nr_W_3l_4p[7][4][3] = { + {{'1', '0', '0'}, {'0', '1', '0'}, {'0', '0', '1'},{'0', '0', '0'}},//pmi 0 + {{'1', '0', '0'}, {'0', '1', '0'}, {'1', '0', '0'},{'0', '0', '1'}}, + {{'1', '0', '0'}, {'0', '1', '0'}, {'n', '0', '0'},{'0', '0', '1'}}, + {{'1', '1', '1'}, {'1', 'n', '1'}, {'1', '1', 'n'},{'1', 'n', 'n'}},//pmi 3 + {{'1', '1', '1'}, {'1', 'n', '1'}, {'j', 'j', 'o'},{'j', 'o', 'o'}},//pmi 4 + {{'1', '1', '1'}, {'n', '1', 'n'}, {'1', '1', 'n'},{'n', '1', '1'}}, + {{'1', '1', '1'}, {'n', '1', 'n'}, {'j', 'j', 'o'},{'o', 'j', 'j'}} +}; + +//Table 6.3.1.5-7 Precoding Matrix W 4 layers 4 antenna ports 'n' = -1 and 'o' = -j +char nr_W_4l_4p[5][4][4] = { + {{'1', '0', '0', '0'}, {'0', '1', '0', '0'}, {'0', '0', '1', '0'}, {'0', '0', '0', '1'}},//pmi 0 + {{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'1', 'n', '0', '0'}, {'0', '0', '1', 'n'}}, + {{'1', '1', '0', '0'}, {'0', '0', '1', '1'}, {'j', 'o', '0', '0'}, {'0', '0', 'j', 'o'}}, + {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'1', '1', 'n', 'n'}, {'1', 'n', 'n', '1'}},//pmi 3 + {{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'j', 'j', 'o', 'o'}, {'j', 'o', 'o', 'j'}}//pmi 4 +}; + void nr_modulation(uint32_t *in, uint32_t length, uint16_t mod_order, @@ -37,7 +132,7 @@ void nr_modulation(uint32_t *in, uint32_t i,j; uint32_t bit_cnt; uint64_t x,x1,x2; - + #if defined(__SSE2__) __m128i *nr_mod_table128; __m128i *out128; @@ -56,7 +151,7 @@ void nr_modulation(uint32_t *in, // the bits that are left out i = i*8/2; nr_mod_table32 = (int32_t*) nr_qpsk_mod_table; - while (i>((i*2)&0x7)) & mask); out32[i] = nr_mod_table32[idx]; i++; @@ -78,7 +173,7 @@ void nr_modulation(uint32_t *in, out64[i] = nr_16qam_byte_mod_table[in_bytes[i]]; // the bits that are left out i = i*8/4; - while (i>((i*4)&0x7)) & mask); out32[i] = nr_16qam_mod_table[idx]; i++; @@ -88,7 +183,7 @@ void nr_modulation(uint32_t *in, case 6: j = 0; for (i=0; i>12)&4095; @@ -140,7 +235,7 @@ void nr_modulation(uint32_t *in, bit_cnt += 24; } return; - + case 8: nr_mod_table32 = (int32_t*) nr_256qam_mod_table; for (i=0; i>1; i++) @@ -186,8 +281,8 @@ void nr_layer_mapping(int16_t **mod_symbs, for (int l=2; l<5; l++) { tx_layers[l][i<<1] = mod_symbs[1][(3*i+l)<<1]; tx_layers[l][(i<<1)+1] = mod_symbs[1][((3*i+l)<<1)+1]; - } - break; + } + break; case 6: for (int q=0; q<2; q++) @@ -196,7 +291,7 @@ void nr_layer_mapping(int16_t **mod_symbs, tx_layers[l][i<<1] = mod_symbs[q][(3*i+l)<<1]; tx_layers[l][(i<<1)+1] = mod_symbs[q][((3*i+l)<<1)+1]; } - break; + break; case 7: for (int i=0; id_mod; - for (int i=0; i>15; tx_layers[0][(i<<1)+1] = (mod_symbs[(i<<1)+1]*AMP)>>15; } - break; + break; case 2: case 3: case 4: mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; - for (int i=0; i>15; tx_layers[l][(i<<1)+1] = (mod_symbs[((n_layers*i+l)<<1)+1]*AMP)>>15; } } - break; + break; case 5: mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; @@ -271,11 +366,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, tx_layers[l][i<<1] = (mod_symbs[(3*i+l)<<1]*AMP)>>15; tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15; } - break; + break; case 6: - for (int q=0; q<2; q++){ - + for (int q=0; q<2; q++) { mod_symbs = (int16_t *)ulsch_ue[q]->d_mod; for (int i=0; i>15; } } - break; + break; case 7: mod_symbs = (int16_t *)ulsch_ue[1]->d_mod; @@ -302,11 +396,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, tx_layers[l][i<<1] = (mod_symbs[((i<<2)+l)<<1]*AMP)>>15; tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15; } - break; + break; case 8: - for (int q=0; q<2; q++){ - + for (int q=0; q<2; q++) { mod_symbs = (int16_t *)ulsch_ue[q]->d_mod; for (int i=0; i>2; i++) @@ -315,20 +408,20 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15; } } - break; + break; - default: - AssertFatal(0, "Invalid number of layers %d\n", n_layers); + default: + AssertFatal(0, "Invalid number of layers %d\n", n_layers); } } void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) { -#if defined(__x86_64__) || defined(__i386__) - __m128i dft_in128[1][1200], dft_out128[1][1200]; +#if defined(__x86_64__) || +defined(__i386__) + __m128i dft_in128[1][3240], dft_out128[1][3240]; #elif defined(__arm__) - int16x8_t dft_in128[1][1200], dft_out128[1][1200]; + int16x8_t dft_in128[1][3240], dft_out128[1][3240]; #endif uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0]; @@ -340,8 +433,10 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) int16x8_t norm128; #endif - for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { - dft_in0[ip] = d[i]; + if ((Msc_PUSCH % 1536) > 0) { + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { + dft_in0[ip] = d[i]; + } } switch (Msc_PUSCH) { @@ -480,7 +575,7 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) break; case 972: - dft(DFT_960,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + dft(DFT_972,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); break; case 1080: @@ -494,43 +589,198 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) case 1200: dft(DFT_1200,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); break; + + case 1296: + dft(DFT_1296,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1440: + dft(DFT_1440,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1500: + dft(DFT_1500,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1536: + //dft(DFT_1536,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + dft(DFT_1536,(int16_t*)d, (int16_t*)z, 1); + break; + + case 1620: + dft(DFT_1620,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1728: + dft(DFT_1728,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1800: + dft(DFT_1800,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1920: + dft(DFT_1920,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 1944: + dft(DFT_1944,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2160: + dft(DFT_2160,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2304: + dft(DFT_2304,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2400: + dft(DFT_2400,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2592: + dft(DFT_2592,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2700: + dft(DFT_2700,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2880: + dft(DFT_2880,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 2916: + dft(DFT_2916,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 3000: + dft(DFT_3000,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + case 3072: + //dft(DFT_3072,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + dft(DFT_3072,(int16_t*)d, (int16_t*)z, 1); + break; + + case 3240: + dft(DFT_3240,(int16_t*)dft_in0, (int16_t*)dft_out0, 1); + break; + + default: + // should not be reached + LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH ); + return; + } - for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { - z[i] = dft_out0[ip]; + + if ((Msc_PUSCH % 1536) > 0) { + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) + z[i] = dft_out0[ip]; } + } -void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq) { +void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) { + + uint64_t dl_CarrierFreq = fp->dl_CarrierFreq; + uint64_t ul_CarrierFreq = fp->ul_CarrierFreq; + double f[2] = {(double)dl_CarrierFreq, (double)ul_CarrierFreq}; const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10; const double Tc=(1/480e3/4096); const double Nu=2048*64*(1/(float)(1<numerology_index)); - const double f0= (double)CarrierFreq; 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; - poff = 2*M_PI*((Ncp0*Tc))*f0; - exp_re = cos(poff); - exp_im = sin(-poff); - fp->symbol_rotation[0]=(int16_t)floor(exp_re*32767); - fp->symbol_rotation[1]=(int16_t)floor(exp_im*32767); - LOG_I(PHY,"Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n",f0,nsymb); - LOG_I(PHY,"Symbol rotation %d/%d => (%d,%d)\n",0,nsymb,fp->symbol_rotation[0],fp->symbol_rotation[1]); - for (int l=1;lnumerology_index))) Ncp=Ncp0; - else Ncp=Ncp1; - tl += (Nu+Ncpm1)*Tc; - poff = 2*M_PI*(tl + (Ncp*Tc))*f0; - exp_re = cos(poff); - exp_im = sin(-poff); - fp->symbol_rotation[l<<1]=(int16_t)floor(exp_re*32767); - fp->symbol_rotation[1+(l<<1)]=(int16_t)floor(exp_im*32767); - LOG_I(PHY,"Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",l,nsymb,tl,fp->symbol_rotation[l<<1],fp->symbol_rotation[1+(l<<1)], - (poff/2/M_PI)-floor(poff/2/M_PI)); - Ncpm1=Ncp; + for (uint8_t ll = 0; ll < 2; ll++){ + + double f0 = f[ll]; + double Ncpm1 = Ncp0; + int16_t *symbol_rotation = fp->symbol_rotation[ll]; + + double tl = 0; + double poff = 2 * M_PI * ((Ncp0 * Tc)) * f0; + double exp_re = cos(poff); + double exp_im = sin(-poff); + symbol_rotation[0] = (int16_t)floor(exp_re * 32767); + symbol_rotation[1] = (int16_t)floor(exp_im * 32767); + LOG_I(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb); + LOG_I(PHY, "Symbol rotation %d/%d => (%d,%d)\n", + 0, + nsymb, + symbol_rotation[0], + symbol_rotation[1]); + + for (int l = 1; l < nsymb; l++) { + + double Ncp; + if (l == (7 * (1 << fp->numerology_index))) { + Ncp = Ncp0; + } else { + Ncp = Ncp1; + } + + tl += (Nu + Ncpm1) * Tc; + poff = 2 * M_PI * (tl + (Ncp * Tc)) * f0; + exp_re = cos(poff); + exp_im = sin(-poff); + symbol_rotation[l<<1] = (int16_t)floor(exp_re * 32767); + symbol_rotation[1 + (l<<1)] = (int16_t)floor(exp_im * 32767); + + LOG_I(PHY, "Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n", + l, + nsymb, + tl, + symbol_rotation[l<<1], + symbol_rotation[1 + (l<<1)], + (poff / 2 / M_PI) - floor(poff / 2 / M_PI)); + + Ncpm1 = Ncp; + + } } } + +int nr_layer_precoder(int16_t **datatx_F_precoding, char *prec_matrix, uint8_t n_layers, int32_t re_offset) +{ + int32_t precodatatx_F = 0; + + for (int al = 0; al>15); + ((int16_t *)precodatatx_F)[1] = (int16_t)((((int16_t *)precodatatx_F)[1]*ONE_OVER_SQRT2_Q15)>>15);*/ +} diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 3d2be905ac..547d20952f 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -28,7 +28,13 @@ #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" #define DMRS_MOD_ORDER 2 - +/*Precoding matices: W[pmi][antenna_port][layer]*/ +extern char nr_W_1l_2p[6][2][1]; +extern char nr_W_2l_2p[3][2][2]; +extern char nr_W_1l_4p[28][4][1]; +extern char nr_W_2l_4p[22][4][2]; +extern char nr_W_3l_4p[7][4][3]; +extern char nr_W_4l_4p[5][4][4]; /*! \brief Perform NR modulation. TS 38.211 V15.4.0 subclause 5.1 @param[in] in, Pointer to input bits @param[in] length, size of input bits @@ -74,7 +80,6 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, \param symbol symbol within slot (0..12/14) \param Ns Slot number (0..19) \param sample_offset offset within rxdata (points to beginning of subframe) -\param no_prefix if 1 prefix is removed by HW */ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, @@ -82,8 +87,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdataF, unsigned char symbol, unsigned char Ns, - int sample_offset, - int no_prefix); + int sample_offset); /*! \brief This function implements the dft transform precoding in PUSCH @@ -100,7 +104,8 @@ int nr_beam_precoding(int32_t **txdataF, int slot, int symbol, int aa, - int nb_antenna_ports + int nb_antenna_ports, + int offset ); void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, @@ -110,7 +115,7 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, int nsymb, int length); -void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq); +void init_symbol_rotation(NR_DL_FRAME_PARMS *fp); void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdataF, @@ -118,4 +123,14 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, int first_symbol, int nsymb, int length); + +/*! \brief Perform NR precoding. TS 38.211 V15.4.0 subclause 6.3.1.5 + @param[in] datatx_F_precoding, Pointer to n_layers*re data array + @param[in] prec_matrix, Pointer to precoding matrix + @param[in] n_layers, number of DLSCH layers +*/ +int nr_layer_precoder(int16_t **datatx_F_precoding, + char *prec_matrix, + uint8_t n_layers, + int32_t re_offset); #endif diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 2d86b46742..8cf9f05b9b 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -306,15 +306,23 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, int length) { int symb_offset = (slot%fp->slots_per_subframe)*fp->symbols_per_slot; + int16_t *symbol_rotation = fp->symbol_rotation[0]; + for (int sidx=0;sidxsymbol_rotation[2*(sidx+first_symbol+symb_offset)],fp->symbol_rotation[1+2*(sidx+first_symbol+symb_offset)]); - rotate_cpx_vector(trxdata+(sidx*length*2), - &fp->symbol_rotation[2*(sidx+first_symbol+symb_offset)], - trxdata+(sidx*length*2), - length, - 15); + first_symbol + sidx, + slot, + sidx + first_symbol + symb_offset, + length, + symbol_rotation[2 * (sidx + first_symbol + symb_offset)], + symbol_rotation[1 + 2 * (sidx + first_symbol + symb_offset)]); + + rotate_cpx_vector(trxdata + (sidx * length * 2), + &symbol_rotation[2 * (sidx + first_symbol + symb_offset)], + trxdata + (sidx * length * 2), + length, + 15); } } diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 60b28d4ad1..0be635ba0b 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -29,364 +29,121 @@ //#define DEBUG_FEP -#define SOFFSET 0 - /*#ifdef LOG_I #undef LOG_I #define LOG_I(A,B...) printf(A) #endif*/ +dft_size_idx_t get_dft_size_idx(uint16_t ofdm_symbol_size) +{ + switch (ofdm_symbol_size) { + case 128: + return DFT_128; + + case 256: + return DFT_256; + + case 512: + return DFT_512; + + case 1024: + return DFT_1024; + + case 1536: + return DFT_1536; + + case 2048: + return DFT_2048; + + case 3072: + return DFT_3072; + + case 4096: + return DFT_4096; + + case 6144: + return DFT_6144; + + case 8192: + return DFT_8192; + + default: + printf("unsupported ofdm symbol size \n"); + assert(0); + } + + return DFT_SIZE_IDXTABLESIZE; +} + int nr_slot_fep(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, unsigned char symbol, - unsigned char Ns, - int sample_offset, - int no_prefix) + unsigned char Ns) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - NR_UE_COMMON *common_vars = &ue->common_vars; - unsigned char aa; + NR_UE_COMMON *common_vars = &ue->common_vars; + + AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1); + AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1); + unsigned int nb_prefix_samples; unsigned int nb_prefix_samples0; - unsigned int abs_symbol; if (ue->is_synchronized) { - nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); - nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0); - } - else { - nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); - nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples); - } - //unsigned int subframe_offset;//,subframe_offset_F; - unsigned int slot_offset; - //int i; - unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10; - unsigned int rx_offset; - - - dft_size_idx_t dftsize; - int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs - - switch (frame_parms->ofdm_symbol_size) { - case 128: - dftsize = DFT_128; - break; - - case 256: - dftsize = DFT_256; - break; - - case 512: - dftsize = DFT_512; - break; - - case 1024: - dftsize = DFT_1024; - break; - - case 1536: - dftsize = DFT_1536; - break; - - case 2048: - dftsize = DFT_2048; - break; - - case 3072: - dftsize = DFT_3072; - break; - - case 4096: - dftsize = DFT_4096; - break; - - case 8192: - dftsize = DFT_8192; - break; - - default: - printf("unsupported ofdm symbol size \n"); - assert(0); - } - - if (no_prefix) { - slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns); + nb_prefix_samples = frame_parms->nb_prefix_samples; + nb_prefix_samples0 = frame_parms->nb_prefix_samples0; } else { - slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); + nb_prefix_samples = frame_parms->nb_prefix_samples; + nb_prefix_samples0 = frame_parms->nb_prefix_samples; } - /*if (l<0 || l>=7-frame_parms->Ncp) { - printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp); - return(-1); - }*/ + dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size); + // This is for misalignment issues + int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); - if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) { - printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1); - return(-1); - } + unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); + unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol; + for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) + rx_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; + rx_offset += frame_parms->ofdm_symbol_size * symbol; - for (aa=0; aanb_antennas_rx; aa++) { - 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 - // rx_offset = rx_offset&0xfffffff8; + // use OFDM symbol from within 1/8th of the CP to avoid ISI + rx_offset -= nb_prefix_samples / 8; #ifdef DEBUG_FEP - // if (ue->frame <100) - /*LOG_I(PHY,*/printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n", - Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples); + // if (ue->frame <100) + printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n", + Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset); #endif - abs_symbol = Ns * frame_parms->symbols_per_slot + symbol; - - for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++) - rx_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; + for (unsigned char aa=0; aanb_antennas_rx; aa++) { + 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(int32_t)); - rx_offset += frame_parms->ofdm_symbol_size * symbol; - - if (abs_symbol%(0x7<numerology_index)) { - - rx_offset += nb_prefix_samples; - if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) - memcpy((short*) &common_vars->rxdata[aa][frame_length_samples], - (short*) &common_vars->rxdata[aa][0], - frame_parms->ofdm_symbol_size*sizeof(int)); - - if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs - memcpy((void *)tmp_dft_in, - (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[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[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); -#if UE_TIMING_TRACE - stop_meas(&ue->rx_dft_stats); -#endif - } - } else { - - rx_offset += nb_prefix_samples0; - if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) - memcpy((void *) &common_vars->rxdata[aa][frame_length_samples], - (void *) &common_vars->rxdata[aa][0], - frame_parms->ofdm_symbol_size*sizeof(int)); -#if UE_TIMING_TRACE - start_meas(&ue->rx_dft_stats); -#endif - - if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs - memcpy((void *)tmp_dft_in, - (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[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[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); - } -#if UE_TIMING_TRACE - stop_meas(&ue->rx_dft_stats); -#endif + int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset]; + // if input to dft is not 256-bit aligned + if ((rx_offset & 7) != 0) { + memcpy((void *)&tmp_dft_in[0], + (void *)&common_vars->rxdata[aa][rx_offset], + frame_parms->ofdm_symbol_size * sizeof(int32_t)); + rxdata_ptr = (int16_t *)tmp_dft_in; } -#ifdef DEBUG_FEP - // if (ue->frame <100) - printf("slot_fep: symbol %d rx_offset %u\n", symbol, rx_offset); -#endif - - 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[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], - (int16_t*)&rot2, - (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); - - } - - -#ifdef DEBUG_FEP - printf("slot_fep: done\n"); -#endif - return(0); -} - -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, - int no_prefix) -{ - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - NR_UE_COMMON *common_vars = &ue->common_vars; - unsigned char aa; - unsigned int nb_prefix_samples; - unsigned int nb_prefix_samples0; - unsigned int abs_symbol; - if (ue->is_synchronized) { - nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); - nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0); - } - else { - nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); - nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples); - } - //unsigned int subframe_offset;//,subframe_offset_F; - unsigned int slot_offset; - //int i; - unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10; - unsigned int rx_offset; - - - dft_size_idx_t dftsize; - int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs - - switch (frame_parms->ofdm_symbol_size) { - case 128: - dftsize = DFT_128; - break; - - case 256: - dftsize = DFT_256; - break; - - case 512: - dftsize = DFT_512; - break; - - case 1024: - dftsize = DFT_1024; - break; - - case 1536: - dftsize = DFT_1536; - break; - - case 2048: - dftsize = DFT_2048; - break; - - case 3072: - dftsize = DFT_3072; - break; - - case 4096: - dftsize = DFT_4096; - break; - - case 8192: - dftsize = DFT_8192; - break; - - default: - printf("unsupported ofdm symbol size \n"); - assert(0); - } - - if (no_prefix) { - slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns); - } else { - slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); - } - - /*if (l<0 || l>=7-frame_parms->Ncp) { - printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp); - return(-1); - }*/ - - if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) { - printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1); - return(-1); - } - - for (aa=0; aanb_antennas_rx; aa++) { - 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 - // rx_offset = rx_offset&0xfffffff8; - -#ifdef DEBUG_FEP - // if (ue->frame <100) - /*LOG_I(PHY,*/printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n", - Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples); -#endif - - abs_symbol = Ns * frame_parms->symbols_per_slot + symbol; - - for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++) - rx_offset += (abs_symbol%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; - - rx_offset += frame_parms->ofdm_symbol_size * symbol; - - if (abs_symbol%(0x7<numerology_index)) { - - rx_offset += nb_prefix_samples; - if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) - memcpy((short*) &common_vars->rxdata[aa][frame_length_samples], - (short*) &common_vars->rxdata[aa][0], - frame_parms->ofdm_symbol_size*sizeof(int)); - - if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs - memcpy((void *)tmp_dft_in, - (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[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); + start_meas(&ue->rx_dft_stats); #endif + dft(dftsize, + rxdata_ptr, + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + 1); - dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset], - (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); + stop_meas(&ue->rx_dft_stats); #endif - } - } else { - - rx_offset += nb_prefix_samples0; - if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) - memcpy((void *) &common_vars->rxdata[aa][frame_length_samples], - (void *) &common_vars->rxdata[aa][0], - frame_parms->ofdm_symbol_size*sizeof(int)); -#if UE_TIMING_TRACE - start_meas(&ue->rx_dft_stats); -#endif - - if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs - memcpy((void *)tmp_dft_in, - (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[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[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); - } -#if UE_TIMING_TRACE - stop_meas(&ue->rx_dft_stats); -#endif - - - } 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]; + int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol+symb_offset]; ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; #ifdef DEBUG_FEP @@ -400,14 +157,121 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, (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); - } - #ifdef DEBUG_FEP printf("slot_fep: done\n"); #endif - return(0); + + return 0; +} + +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) +{ + NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + NR_UE_COMMON *common_vars = &ue->common_vars; + + AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1); + AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1); + + unsigned int nb_prefix_samples; + unsigned int nb_prefix_samples0; + if (ue->is_synchronized) { + nb_prefix_samples = frame_parms->nb_prefix_samples; + nb_prefix_samples0 = frame_parms->nb_prefix_samples0; + } + else { + nb_prefix_samples = frame_parms->nb_prefix_samples; + nb_prefix_samples0 = frame_parms->nb_prefix_samples; + } + unsigned int frame_length_samples = frame_parms->samples_per_frame; + + dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size); + // This is for misalignment issues + int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); + + unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); + unsigned int rx_offset = sample_offset + slot_offset; + unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol; + for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) + rx_offset += (abs_symbol%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; + rx_offset += frame_parms->ofdm_symbol_size * symbol; + +#ifdef DEBUG_FEP + // if (ue->frame <100) + printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n", + Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples); +#endif + + for (unsigned char aa=0; aanb_antennas_rx; aa++) { + 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(int32_t)); + + int16_t *rxdata_ptr; + + if (frame_length_samples - rx_offset < frame_parms->ofdm_symbol_size) { + + memcpy((void *)&tmp_dft_in[0], + (void *)&common_vars->rxdata[aa][rx_offset], + (frame_length_samples - rx_offset) * sizeof(int32_t)); + memcpy((void *)&tmp_dft_in[frame_length_samples - rx_offset], + (void *)&common_vars->rxdata[aa][0], + (frame_parms->ofdm_symbol_size - (frame_length_samples - rx_offset)) * sizeof(int32_t)); + rxdata_ptr = (int16_t *)&tmp_dft_in[0]; + + } else if ((rx_offset & 7) != 0) { + + // if input to dft is not 256-bit aligned + memcpy((void *)&tmp_dft_in[0], + (void *)&common_vars->rxdata[aa][rx_offset], + frame_parms->ofdm_symbol_size * sizeof(int32_t)); + rxdata_ptr = (int16_t *)&tmp_dft_in[0]; + + } else { + + // use dft input from RX buffer directly + rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset]; + + } + +#if UE_TIMING_TRACE + start_meas(&ue->rx_dft_stats); +#endif + + dft(dftsize, + rxdata_ptr, + (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 + + int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; + int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset]; + ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; + +#ifdef DEBUG_FEP + // if (ue->frame <100) + printf("slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset, + 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[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + (int16_t*)&rot2, + (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); + } + +#ifdef DEBUG_FEP + printf("slot_fep: done\n"); +#endif + + return 0; } @@ -416,89 +280,60 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdataF, unsigned char symbol, unsigned char Ns, - int sample_offset, - int no_prefix) + int sample_offset) { - int32_t slot_offset, rxdata_offset; - - unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); - unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0); + unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples; + unsigned int nb_prefix_samples0 = frame_parms->nb_prefix_samples0; - int tmp_dft_in[8192] __attribute__ ((aligned (32))); + dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size); + // This is for misalignment issues + int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); - dft_size_idx_t dftsize; + unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); - switch (frame_parms->ofdm_symbol_size) { - case 128: - dftsize = DFT_128; - break; + // offset of first OFDM symbol + int32_t rxdata_offset = slot_offset + nb_prefix_samples0; + // offset of n-th OFDM symbol + rxdata_offset += symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples); + // use OFDM symbol from within 1/8th of the CP to avoid ISI + rxdata_offset -= nb_prefix_samples / 8; - case 256: - dftsize = DFT_256; - break; + int16_t *rxdata_ptr; - case 512: - dftsize = DFT_512; - break; + if(sample_offset > rxdata_offset) { - case 1024: - dftsize = DFT_1024; - break; + memcpy((void *)&tmp_dft_in[0], + (void *)&rxdata[frame_parms->samples_per_frame - sample_offset + rxdata_offset], + (sample_offset - rxdata_offset) * sizeof(int32_t)); + memcpy((void *)&tmp_dft_in[sample_offset - rxdata_offset], + (void *)&rxdata[0], + (frame_parms->ofdm_symbol_size - sample_offset + rxdata_offset) * sizeof(int32_t)); + rxdata_ptr = (int16_t *)&tmp_dft_in[0]; - case 1536: - dftsize = DFT_1536; - break; + } else if (((rxdata_offset - sample_offset) & 7) != 0) { - case 2048: - dftsize = DFT_2048; - break; + // if input to dft is not 256-bit aligned + memcpy((void *)&tmp_dft_in[0], + (void *)&rxdata[rxdata_offset - sample_offset], + (frame_parms->ofdm_symbol_size) * sizeof(int32_t)); + rxdata_ptr = (int16_t *)&tmp_dft_in[0]; - case 4096: - dftsize = DFT_4096; - break; + } else { - case 8192: - dftsize = DFT_8192; - break; + // use dft input from RX buffer directly + rxdata_ptr = (int16_t *)&rxdata[rxdata_offset - sample_offset]; - default: - dftsize = DFT_512; - break; } - - slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); - if(symbol == 0) - rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET; - else - rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET; - - if(sample_offset>rxdata_offset) { - memcpy1((void *)tmp_dft_in, - (void *) &rxdata[frame_parms->samples_per_frame-sample_offset+rxdata_offset], - (sample_offset-rxdata_offset)*sizeof(int)); - - memcpy1((void *)&tmp_dft_in[sample_offset-rxdata_offset], - (void *) &rxdata[0], - (frame_parms->ofdm_symbol_size-sample_offset+rxdata_offset)*sizeof(int)); - - dft(dftsize,(int16_t *)&tmp_dft_in, - (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); - } - else { - //dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset], - // (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); - 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); - } + dft(dftsize, + rxdata_ptr, + (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], + 1); // clear DC carrier from OFDM symbols rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0; - return(0); + return 0; } void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, @@ -513,7 +348,7 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, for (int symbol=0;symbolsymbol_rotation)[symbol+symb_offset]; + uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[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], diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index ec55eabf31..d3e33a91a8 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -20,12 +20,12 @@ */ /*! \file PHY/NR_ESTIMATION/nr_measurements_gNB.c -* \brief TA estimation for TA updates -* \author Ahmed Hussein +* \brief gNB measurement routines +* \author Ahmed Hussein, G. Casati, K. Saaifan * \date 2019 * \version 0.1 * \company Fraunhofer IIS -* \email: ahmed.hussein@iis.fraunhofer.de +* \email: ahmed.hussein@iis.fraunhofer.de, guido.casati@iis.fraunhofer.de, khodr.saaifan@iis.fraunhofer.de * \note * \warning */ @@ -35,24 +35,24 @@ #include "PHY/phy_extern.h" #include "nr_ul_estimation.h" +extern openair0_config_t openair0_cfg[MAX_CARDS]; + int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) { - int temp, i, aa, max_pos = 0, max_val = 0; - short Re, Im; - uint8_t cyclic_shift = 0; + int i, aa, max_pos = 0, max_val = 0; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id]; int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time; - int sync_pos = (frame_parms->ofdm_symbol_size - cyclic_shift*frame_parms->ofdm_symbol_size/12) % (frame_parms->ofdm_symbol_size); + int sync_pos = frame_parms->nb_prefix_samples / 8; for (i = 0; i < frame_parms->ofdm_symbol_size; i++) { - temp = 0; + int temp = 0; for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { - Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; - Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; + short Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; + short Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -75,14 +75,17 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB) { NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; NR_gNB_COMMON *common_vars = &gNB->common_vars; PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements; + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + double rx_gain = openair0_cfg[0].rx_gain[0]; + double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0]; uint32_t *rb_mask = gNB->rb_mask_ul; int symbol = gNB->ulmask_symb; int rb, offset, nb_rb; - uint32_t n0_power_tot, n0_subband_power_temp=0; + uint32_t n0_subband_power_temp = 0; int32_t *ul_ch; if (symbol>-1) { - n0_power_tot = 0; + measurements->n0_power_tot = 0; for (int aarx=0; aarxnb_antennas_rx; aarx++) { nb_rb = 0; for (rb=0; rbN_RB_UL; rb++) { @@ -95,11 +98,76 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB) { n0_subband_power_temp += signal_energy_nodc(ul_ch,12); } } - measurements->n0_power[aarx] = n0_subband_power_temp/nb_rb; - measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]); - n0_power_tot += measurements->n0_power[aarx]; + + if (nb_rb != 0) { + measurements->n0_power[aarx] = n0_subband_power_temp/nb_rb; + measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]); + measurements->n0_power_tot += measurements->n0_power[aarx]; + } + } - measurements->n0_power_tot_dB = dB_fixed(n0_power_tot); + + measurements->n0_power_tot_dB = dB_fixed(measurements->n0_power_tot); + measurements->n0_power_tot_dBm = measurements->n0_power_tot_dB + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size); + + LOG_D(PHY, "In %s: tot n0 power %d dBm for %d RBs (tot N0 power = %d)\n", __FUNCTION__, measurements->n0_power_tot_dBm, nb_rb, measurements->n0_power_tot); + } } +// Scope: This function computes the UL SNR from the UL channel estimates +// +// Todo: +// - averaging IIR filter for RX power and noise +void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol){ + + int rx_power_tot[NUMBER_OF_NR_ULSCH_MAX]; + int rx_power[NUMBER_OF_NR_ULSCH_MAX][NB_ANTENNAS_RX]; + unsigned short rx_power_avg_dB[NUMBER_OF_NR_ULSCH_MAX]; + unsigned short rx_power_tot_dB[NUMBER_OF_NR_ULSCH_MAX]; + + double rx_gain = openair0_cfg[0].rx_gain[0]; + double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0]; + PHY_MEASUREMENTS_gNB *meas = &gNB->measurements; + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + int ch_offset = fp->ofdm_symbol_size * symbol; + int N_RB_UL = gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu.rb_size; + + rx_power_tot[ulsch_id] = 0; + + for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++){ + + rx_power[ulsch_id][aarx] = 0; + + for (int aatx = 0; aatx < fp->nb_antennas_tx; aatx++){ + + meas->rx_spatial_power[ulsch_id][aatx][aarx] = (signal_energy_nodc(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][ch_offset], N_RB_UL * NR_NB_SC_PER_RB)); + + if (meas->rx_spatial_power[ulsch_id][aatx][aarx] < 0) { + meas->rx_spatial_power[ulsch_id][aatx][aarx] = 0; + } + + meas->rx_spatial_power_dB[ulsch_id][aatx][aarx] = (unsigned short) dB_fixed(meas->rx_spatial_power[ulsch_id][aatx][aarx]); + rx_power[ulsch_id][aarx] += meas->rx_spatial_power[ulsch_id][aatx][aarx]; + + } + + rx_power_tot[ulsch_id] += rx_power[ulsch_id][aarx]; + + } + + rx_power_tot_dB[ulsch_id] = (unsigned short) dB_fixed(rx_power_tot[ulsch_id]); + rx_power_avg_dB[ulsch_id] = rx_power_tot_dB[ulsch_id]; + + meas->wideband_cqi_tot[ulsch_id] = dB_fixed2(rx_power_tot[ulsch_id], meas->n0_power_tot); + meas->rx_rssi_dBm[ulsch_id] = rx_power_avg_dB[ulsch_id] + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size); + + LOG_D(PHY, "[ULSCH %d] RSSI %d dBm/RE, RSSI (digital) %d dB (N_RB_UL %d), WBand CQI tot %d dB, N0 Power tot %d\n", + ulsch_id, + meas->rx_rssi_dBm[ulsch_id], + rx_power_avg_dB[ulsch_id], + N_RB_UL, + meas->wideband_cqi_tot[ulsch_id], + meas->n0_power_tot); + +} diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 713e71674b..967868f803 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -61,8 +61,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, debug_ch_est = fopen("debug_ch_est.txt","w"); #endif - //uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1]; - uint8_t nushift; int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates; int **rxdataF = gNB->common_vars.rxdataF; @@ -75,16 +73,21 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, symbol_offset = gNB->frame_parms.ofdm_symbol_size*symbol; k = bwp_start_subcarrier; - int re_offset = k; + int re_offset; uint16_t nb_rb_pusch = pusch_pdu->rb_size; -/* #ifdef DEBUG_CH - printf("PUSCH Channel Estimation : ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", ,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size, - gNB->frame_parms.Ncp,l,Ns,k, symbol); + LOG_D(PHY, "In %s: ch_offset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n", + __FUNCTION__, + ch_offset, + symbol_offset, + gNB->frame_parms.ofdm_symbol_size, + Ns, + k, + symbol); #endif -*/ + switch (nushift) { case 0: fl = filt8_l0; @@ -124,9 +127,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //------------------generate DMRS------------------// - if (pusch_pdu->transform_precoding == transform_precoder_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 { // if transform precoding or SC-FDMA is enabled in Uplink // NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible @@ -151,25 +154,32 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //------------------------------------------------// - #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)]); + for (int i = 0; i < (6 * nb_rb_pusch); i++) { + LOG_I(PHY, "In %s: %d + j*(%d)\n", + __FUNCTION__, + ((int16_t*)pilot)[2 * i], + ((int16_t*)pilot)[1 + (2 * i)]); + } #endif + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + re_offset = k; /* Initializing the Resource element offset for each Rx antenna */ + pil = (int16_t *)&pilot[0]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + re_offset = k; memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size)); #ifdef DEBUG_PUSCH - printf("symbol_offset %d, nushift %d\n",symbol_offset,nushift); - printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL); - printf("bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n",bwp_start_subcarrier,k,gNB->frame_parms.first_carrier_offset,nb_rb_pusch); - printf("rxF addr %p p %d\n", rxF,p); - printf("ul_ch addr %p nushift %d\n",ul_ch,nushift); + LOG_I(PHY, "In %s symbol_offset %d, nushift %d\n", __FUNCTION__, symbol_offset, nushift); + LOG_I(PHY, "In %s ch est pilot addr %p, N_RB_UL %d\n", __FUNCTION__, &pilot[0], gNB->frame_parms.N_RB_UL); + LOG_I(PHY, "In %s bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n", __FUNCTION__, bwp_start_subcarrier, k, gNB->frame_parms.first_carrier_offset, nb_rb_pusch); + LOG_I(PHY, "In %s rxF addr %p p %d\n", __FUNCTION__, rxF, p); + LOG_I(PHY, "In %s ul_ch addr %p nushift %d\n", __FUNCTION__, ul_ch, nushift); #endif //if ((gNB->frame_parms.N_RB_UL&1)==0) { @@ -180,9 +190,18 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH - printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - printf("pilot 0 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data 0 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3])); + LOG_I(PHY, "In %s ch 0 %d\n", __FUNCTION__, ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); + LOG_I(PHY, "In %s pilot 0 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n", + __FUNCTION__, + rxF[0], + rxF[1], + dBc(rxF[0],rxF[1]), + ch[0], + ch[1], + dBc(ch[0],ch[1]), + pil[0], + pil[1]); + LOG_I(PHY, "In %s data 0 : rxF - > (%d,%d) (%d)\n", __FUNCTION__, rxF[2], rxF[3], dBc(rxF[2],rxF[3])); #endif multadd_real_vector_complex_scalar(fl, @@ -199,9 +218,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH - printf("pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data 1 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3])); + LOG_I(PHY, "In %s pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n", + __FUNCTION__, + rxF[0], + rxF[1], + dBc(rxF[0],rxF[1]), + ch[0], + ch[1], + dBc(ch[0],ch[1]), + pil[0], + pil[1]); + LOG_I(PHY, "In %s data 1 : rxF - > (%d,%d) (%d)\n", + __FUNCTION__, + rxF[2], + rxF[3], + dBc(rxF[2],rxF[3])); #endif + multadd_real_vector_complex_scalar(fml, ch, ul_ch, @@ -215,9 +248,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PUSCH - printf("pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]); - printf("data 2 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3])); + LOG_I(PHY, "In %s pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n", + __FUNCTION__, + rxF[0], + rxF[1], + dBc(rxF[0],rxF[1]), + ch[0], + ch[1], + dBc(ch[0],ch[1]), + pil[0], + pil[1]); + LOG_I(PHY, "In %s data 2 : rxF - > (%d,%d) (%d)\n", + __FUNCTION__, + rxF[2], + rxF[3], + dBc(rxF[2],rxF[3])); #endif + multadd_real_vector_complex_scalar(fmm, ch, ul_ch, diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index a463e21839..7bd004a4d4 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -49,8 +49,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, void gNB_I0_measurements(PHY_VARS_gNB *gNB); -int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id); +void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol); +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, diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 5d62f9dbb9..5a4b1adbb8 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -40,9 +40,9 @@ #include "PHY/defs_gNB.h" /*Table 7.4.1.1.2-1/2 from 38.211 */ -int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}}; +int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}}; int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}}; -int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1},{1,1},{1,-1},{1,1},{1,1}}; +int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}}; int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1}}; // complex conjugate of mod table diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index eefa6270ab..623b86edfb 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -52,22 +52,15 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue) } void nr_gold_pdcch(PHY_VARS_NR_UE* ue, - unsigned short n_idDMRS, - unsigned short length_dmrs) + unsigned short nid) { 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; - for (ns=0; nsframe_parms.slots_per_frame; ns++) { - for (l=0; lframe_parms.symbols_per_slot; l++) { reset = 1; x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17; @@ -82,11 +75,10 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue, } void nr_gold_pdsch(PHY_VARS_NR_UE* ue, - unsigned char ns, unsigned short *n_idDMRS) { unsigned char l; - unsigned int n,x1,x2,x2tmp0; + unsigned int n,x1,x2,x2tmp0,ns; int nscid; unsigned int nid; uint8_t reset; @@ -95,23 +87,21 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue, //unsigned short lbar = 0; for (nscid=0; nscid<2; nscid++) { - if (n_idDMRS) + for (ns=0; nsframe_parms.slots_per_frame; ns++) { + nid = n_idDMRS[nscid]; - else - nid = ue->frame_parms.Nid_cell; - //printf("gold pdsch nid %d lbar %d\n",nid,lbar); + for (l=0; lframe_parms.symbols_per_slot; l++) { - for (l=0; lframe_parms.symbols_per_slot; l++) { + 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); - 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; + 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/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 83b43c54a0..54279a8ad5 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -57,11 +57,9 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, void nr_gold_pbch(PHY_VARS_NR_UE* ue); void nr_gold_pdcch(PHY_VARS_NR_UE* ue, - unsigned short n_idDMRS, - unsigned short length_dmrs); + unsigned short n_idDMRS); void nr_gold_pdsch(PHY_VARS_NR_UE* ue, - unsigned char ns, unsigned short *n_idDMRS); void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, diff --git a/openair1/PHY/NR_REFSIG/scrambling_luts.c b/openair1/PHY/NR_REFSIG/scrambling_luts.c index 3509291e42..2a37a12539 100644 --- a/openair1/PHY/NR_REFSIG/scrambling_luts.c +++ b/openair1/PHY/NR_REFSIG/scrambling_luts.c @@ -51,7 +51,7 @@ void init_byte2m64(void) { ((int16_t*)&byte2m64_re[s])[0],((int16_t*)&byte2m64_im[s])[0], ((int16_t*)&byte2m64_re[s])[1],((int16_t*)&byte2m64_im[s])[1], ((int16_t*)&byte2m64_re[s])[2],((int16_t*)&byte2m64_im[s])[2], - ((int16_t*)&byte2m64_re[s])[3],((int16_t*)&byte2m64_im[s])[3]); + ((int16_t*)&byte2m64_re[s])[3],((int16_t*)&byte2m64_im[s])[3]); } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 469415908f..b7de182ab7 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -30,7 +30,7 @@ * \warning */ -#include + #include "nr_dci.h" #include "nr_dlsch.h" #include "nr_sch_dmrs.h" @@ -85,10 +85,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, // 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 = cset_start_sc + RC.nrmac[gNB->Mod_id]->type0_PDCCH_CSS_config.cset_start_rb*NR_NB_SC_PER_RB; - } + cset_start_sc = frame_parms.first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; for (int d=0;dnumDlDci;d++) { /*The coreset is initialised @@ -228,6 +225,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, 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++; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 1cce5e1174..35c4698761 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -141,25 +141,25 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, 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; + int16_t **txdataF_precoding = (int16_t**)dlsch->txdataF_precoding; 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; if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) { nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData; - n_dmrs = ((rel15->rbSize+rel15->rbStart)*6)<<1; } else { nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData; - n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1; } + n_dmrs = (rel15->rbSize+rel15->rbStart)*nb_re_dmrs; 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[14][n_dmrs] __attribute__ ((aligned(16))); + int16_t mod_dmrs[14][n_dmrs<<1] __attribute__ ((aligned(16))); /* PTRS */ uint16_t beta_ptrs = 1; @@ -265,16 +265,13 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, } #endif - /// Antenna port mapping - //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007 - /// DMRS QPSK modulation 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 + nr_modulation(pdsch_dmrs[l][0], n_dmrs*2, 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 (symbol %d, %d symbols, type %d):\n", l, n_dmrs>>1, dmrs_Type); + printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs, 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]); @@ -291,7 +288,9 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, 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; - + + int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; + #ifdef DEBUG_DLSCH_MAPPING printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n", start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers); @@ -312,9 +311,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime, l0, dmrs_symbol); #endif - uint16_t m=0, dmrs_idx=0, k=0; - - int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; + uint16_t m=0, dmrs_idx=0; // Loop Over OFDM symbols: for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { @@ -348,7 +345,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, nr_modulation(pdsch_dmrs[l][0], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs); } } - k = start_sc; + uint16_t k = start_sc; // Loop Over SCs: for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) { /* check if cuurent RE is PTRS RE*/ @@ -368,12 +365,12 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, /* 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; + txdataF_precoding[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; + txdataF_precoding[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)]); + dmrs_idx, l, k, k_prime, n, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif dmrs_idx++; k_prime++; @@ -382,8 +379,8 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, } /* 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; + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15; + txdataF_precoding[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("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)], @@ -392,17 +389,20 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, 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; + 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)) { + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING - printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", - m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); + printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", + m, l, k, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif - m++; - } + m++; + } + /* mute RE */ + else { + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = 0; + txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = 0; } if (++k >= frame_parms->ofdm_symbol_size) k -= frame_parms->ofdm_symbol_size; @@ -410,9 +410,108 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, } // symbol loop }// layer loop + ///Layer Precoding and Antenna port mapping + // tx_layers 1-8 are mapped on antenna ports 1000-1007 + // The precoding info is supported by nfapi such as num_prgs, prg_size, prgs_list and pm_idx + // The same precoding matrix is applied on prg_size RBs, Thus + // pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1 + // The Precoding matrix: + // The Codebook Type I and Type II are not supported yet. + // We adopt the precoding matrices of PUSCH for 4 layers. + for (int ap=0; apnb_antennas_tx; ap++) { + + for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { + uint16_t k = start_sc; + + for (int rb=0; rbrbSize; rb++) { + //get pmi info + uint8_t pmi; + if (rel15->precodingAndBeamforming.prg_size > 0) + pmi = rel15->precodingAndBeamforming.prgs_list[(int)rb/rel15->precodingAndBeamforming.prg_size].pm_idx; + else + pmi = 0;//no precoding + + if (pmi == 0) {//unitary Precoding + if(apnrOfLayers) + memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k], + (void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + txdataF_offset+ k)], + NR_NB_SC_PER_RB*sizeof(int32_t)); + else + memset((void*)&txdataF[ap][rel15->StartSymbolIndex*frame_parms->ofdm_symbol_size + txdataF_offset +k], + 0, + NR_NB_SC_PER_RB*sizeof(int32_t)); + k += NR_NB_SC_PER_RB; + if (k >= frame_parms->ofdm_symbol_size) { + k -= frame_parms->ofdm_symbol_size; + } + } + else { + //get the precoding matrix weights: + char *W_prec; + switch (frame_parms->nb_antennas_tx) { + case 1://1 antenna port + W_prec = nr_W_1l_2p[pmi][ap]; + break; + case 2://2 antenna ports + if (rel15->nrOfLayers == 1)//1 layer + W_prec = nr_W_1l_2p[pmi][ap]; + else//2 layers + W_prec = nr_W_2l_2p[pmi][ap]; + break; + case 4://4 antenna ports + if (rel15->nrOfLayers == 1)//1 layer + W_prec = nr_W_1l_4p[pmi][ap]; + else if (rel15->nrOfLayers == 2)//2 layers + W_prec = nr_W_2l_4p[pmi][ap]; + else if (rel15->nrOfLayers == 3)//3 layers + W_prec = nr_W_3l_4p[pmi][ap]; + else//4 layers + W_prec = nr_W_4l_4p[pmi][ap]; + break; + default: + LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n"); + W_prec = nr_W_1l_2p[pmi][ap]; + break; + } + for (int i=0; iofdm_symbol_size + k; + int32_t precodatatx_F = nr_layer_precoder(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset+txdataF_offset); + ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0]; + ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1]; +#ifdef DEBUG_DLSCH_MAPPING + printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n", + ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]); +#endif + if (++k >= frame_parms->ofdm_symbol_size) { + k -= frame_parms->ofdm_symbol_size; + } + } + } + } //RB loop + } // symbol loop + }// port loop dlsch->slot_tx[slot]=0; + + // TODO: handle precoding + // this maps the layers onto antenna ports + + // handle beamforming ID + // each antenna port is assigned a beam_index + // since PHY can only handle BF on slot basis we set the whole slot + + // first check if this slot has not already been allocated to another beam + if (gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot]==255) { + for (int j=0;jsymbols_per_slot;j++) + gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot+j] = rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; + } + else { + LOG_W(PHY,"beam index for PDSCH allocation already taken\n"); + } }// dlsch loop + + return 0; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index e6544bbe0c..b441635246 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -61,10 +61,8 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB) if (N_RB != 273) { 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 @@ -110,8 +108,6 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB) harq->d[r] = NULL; } } - free16(harq, sizeof(NR_DL_gNB_HARQ_t)); - harq = NULL; } } @@ -133,7 +129,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, if (N_RB != 273) { a_segments = a_segments*N_RB; a_segments = a_segments/273 +1; - } + } uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment @@ -145,31 +141,30 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, 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; re < OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) { + 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 + 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 + dlsch->txdataF_precoding[layer] = (int32_t *)malloc16(2*14*frame_parms->ofdm_symbol_size*sizeof(int32_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)); + 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)); + 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++) { + for (i=0; i<20; i++) { dlsch->harq_ids[0][i] = 0; dlsch->harq_ids[1][i] = 0; } @@ -268,7 +263,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, float Coderate = 0.0; uint8_t Nl = 4; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN); A = rel15->TBSize[0]<<3; @@ -304,7 +298,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, 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; @@ -323,7 +317,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, 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; @@ -339,17 +333,17 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, 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; @@ -357,7 +351,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, #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]; @@ -369,7 +363,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, 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); @@ -380,23 +374,22 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, 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)); kd[r][k]); } } - - - + #ifdef DEBUG_DLSCH_CODING LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]); #endif - + 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, @@ -423,13 +414,13 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, 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, diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index bd1278b2eb..0bc04e3047 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -241,7 +241,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ///Payload generation memset((void *)pbch, 0, sizeof(NR_gNB_PBCH)); pbch->pbch_a=0; - uint8_t ssb_index = frame_parms->ssb_index; + uint8_t ssb_index = ssb_pdu->ssb_pdu_rel15.SsbBlockIndex; uint8_t *pbch_pdu = (uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload; uint8_t Lmax = frame_parms->Lmax; for (int i=0; iN_RB_UL <= 100) - AssertFatal(1==0,"N_RB_UL %d not support for NR PRACH yet\n",fp->N_RB_UL); - else if (fp->N_RB_UL < 137) { - if (fp->threequarter_fs==0) { - //40 MHz @ 61.44 Ms/s - //50 MHz @ 61.44 Ms/s - prach2 = prach[aa] + (Ncp<<2); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=49152; - dft(DFT_49152,prach2,rxsigF[aa],1); + switch(fp->samples_per_subframe) { + case 15360: + // 10, 15 MHz @ 15.36 Ms/s + prach2 = prach[aa] + (1*Ncp); // Ncp is for 30.72 Ms/s, so divide by 2 to bring to 15.36 Ms/s and multiply by 2 for I/Q + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=12288; + dft(DFT_12288,prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_12288,prach2+24576,rxsigF[aa]+24576,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_12288,prach2+(24576*2),rxsigF[aa]+(24576*2),1); + dft(DFT_12288,prach2+(24576*3),rxsigF[aa]+(24576*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=3072; + for (int i=0;i<4;i++) dft(DFT_3072,prach2+(i*3072*2),rxsigF[aa]+(i*3072*2),1); + reps=4; + } + } else { // 839 sequence + if (prachStartSymbol == 0) prach2+=16; // 8 samples @ 15.36 Ms/s in first symbol of each half subframe (15/30 kHz only) + + dftlen=512; + dft(DFT_512,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_512,prach2+1024,rxsigF[aa]+1024,1); + reps++; + } + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_512,prach2+1024*2,rxsigF[aa]+1024*2,1); + dft(DFT_512,prach2+1024*3,rxsigF[aa]+1024*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_512,prach2+1024*4,rxsigF[aa]+1024*4,1); + dft(DFT_512,prach2+1024*5,rxsigF[aa]+1024*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_512,prach2+(1024*i),rxsigF[aa]+(1024*i),1); + reps+=6; + } } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1); - dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=12288; - for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1); - reps=4; - } - }// 839 sequence - else { - if (prachStartSymbol == 0) - prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) + break; - 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 { // threequarter sampling - // 40 MHz @ 46.08 Ms/s - prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q - if (prach_sequence_length == 0) { - AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n"); - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=36864; - dft(DFT_36864,prach2,rxsigF[aa],1); - reps++; - } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1); - dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=9216; - for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1); - reps=4; - } - } else { - if (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 - else if (fp->N_RB_UL <= 273) { - if (fp->threequarter_fs==0) { - prach2 = prach[aa] + (Ncp<<3); - //80,90,100 MHz @ 122.88 Ms/s + case 30720: + // 20, 25, 30 MHz @ 30.72 Ms/s + prach2 = prach[aa] + (2*Ncp); // Ncp is for 30.72 Ms/s, so just multiply by 2 for I/Q + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=24576; + dft(DFT_24576,prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_24576,prach2+49152,rxsigF[aa]+49152,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_24576,prach2+(49152*2),rxsigF[aa]+(49152*2),1); + dft(DFT_24576,prach2+(49152*3),rxsigF[aa]+(49152*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=6144; + for (int i=0;i<4;i++) dft(DFT_6144,prach2+(i*6144*2),rxsigF[aa]+(i*6144*2),1); + reps=4; + } + } else { // 839 sequence + if (prachStartSymbol == 0) prach2+=32; // 16 samples @ 30.72 Ms/s in first symbol of each half subframe (15/30 kHz only) - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=98304; - dft(DFT_98304,prach2,rxsigF[aa],1); + dftlen=1024; + dft(DFT_1024,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_1024,prach2+2048,rxsigF[aa]+2048,1); + reps++; + } + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_1024,prach2+2048*2,rxsigF[aa]+2048*2,1); + dft(DFT_1024,prach2+2048*3,rxsigF[aa]+2048*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_1024,prach2+2048*4,rxsigF[aa]+2048*4,1); + dft(DFT_1024,prach2+2048*5,rxsigF[aa]+2048*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_1024,prach2+(2048*i),rxsigF[aa]+(2048*i),1); + reps+=6; + } } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1); - reps++; - } - if (prachFormat == 2) { - dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1); - dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1); - reps+=2; - } - if (prachFormat == 3) { - dftlen=24576; - for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1); - reps=4; - } - } - else { - if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + break; - 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 { - AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n"); - prach2 = prach[aa] + (6*Ncp); - // 80 MHz @ 92.16 Ms/s - if (prach_sequence_length == 0) { - if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { - dftlen=73728; - dft(DFT_73728,prach2,rxsigF[aa],1); - reps++; - } - if (prachFormat == 1 || prachFormat == 2) { - dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1); - reps++; - } - if (prachFormat == 3) { - dftlen=18432; - for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1); - reps=4; - } - } else { - if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + case 61440: + // 40, 50, 60 MHz @ 61.44 Ms/s + prach2 = prach[aa] + (4*Ncp); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=49152; + dft(DFT_49152,prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1); + dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=12288; + for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1); + reps=4; + } + } else { // 839 sequence + if (prachStartSymbol == 0) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) - 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; - } - } + 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; + } + } + break; + + case 46080: + // 40 MHz @ 46.08 Ms/s + prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=36864; + dft(DFT_36864,prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1); + dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=9216; + for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1); + reps=4; + } + } else { // 839 sequence + 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; + } + } + break; + + case 122880: + // 70, 80, 90, 100 MHz @ 122.88 Ms/s + prach2 = prach[aa] + (8*Ncp); + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=98304; + dft(DFT_98304,prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1); + dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=24576; + for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1); + reps=4; + } + } else { // 839 sequence + if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + + 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; + } + } + break; + + case 92160: + // 80, 90 MHz @ 92.16 Ms/s + prach2 = prach[aa] + (6*Ncp); + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=73728; + dft(DFT_73728,prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft(DFT_73728,prach2+147456,rxsigF[aa]+147456,1); + reps++; + } + if (prachFormat == 2) { + dft(DFT_73728,prach2+(147456*2),rxsigF[aa]+(147456*2),1); + dft(DFT_73728,prach2+(147456*3),rxsigF[aa]+(147456*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=18432; + for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1); + reps=4; + } + } else { + if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + + 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; + } + } + break; + default: + AssertFatal(1==0,"sample_rate %f MHz not support for NR PRACH yet\n", fp->samples_per_subframe / 1000.0); } } - } else if (mu==3) { if (fp->threequarter_fs) { AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu); @@ -685,7 +780,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, } } else { // This is the high-speed case new_dft = 0; - + nr_fill_du(N_ZC,prach_root_sequence_map); // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this // preamble index and find the corresponding cyclic shift // Check if all shifts for that root have been processed @@ -693,7 +788,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, not_found = 1; new_dft = 1; preamble_index0 -= numshift; - (preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++); + //(preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++); while (not_found == 1) { // current root depending on rootSequenceIndex diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h index be3ba00989..02e594e76a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h @@ -73,6 +73,8 @@ void compute_nr_prach_seq(uint8_t short_sequence, uint8_t rootSequenceIndex, uint32_t X_u[64][839]); +void nr_fill_du(uint16_t N_ZC,uint16_t *prach_root_sequence_map); + void init_nr_prach_tables(int N_ZC); /**@}*/ diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index d990176d79..b572a6e5bb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -320,7 +320,7 @@ void nr_processULSegment(void* arg) { Kr_bytes = Kr>>3; K_bits_F = Kr-ulsch_harq->F; - t_nrLDPC_time_stats procTime; + t_nrLDPC_time_stats procTime = {0}; t_nrLDPC_time_stats* p_procTime = &procTime ; //start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 7e6becb4a8..edca81d501 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -16,10 +16,10 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) { #if defined(__x86_64__) || defined(__i386__) - __m128i idft_in128[1][1200], idft_out128[1][1200]; + __m128i idft_in128[1][3240], idft_out128[1][3240]; __m128i norm128; #elif defined(__arm__) - int16x8_t idft_in128[1][1200], idft_out128[1][1200]; + int16x8_t idft_in128[1][3240], idft_out128[1][3240]; int16x8_t norm128; #endif int16_t *idft_in0 = (int16_t*)idft_in128[0], *idft_out0 = (int16_t*)idft_out128[0]; @@ -28,20 +28,19 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH); - // conjugate input - for (i = 0; i < (Msc_PUSCH>>2); i++) { + if ((Msc_PUSCH % 1536) > 0) { + // conjugate input + for (i = 0; i < (Msc_PUSCH>>2); i++) { #if defined(__x86_64__)||defined(__i386__) - *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]); + *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]); #elif defined(__arm__) - *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); + *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); #endif + } + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) + ((uint32_t*)idft_in0)[ip+0] = z[i]; } - for (i=0,ip=0; i 0) { + for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) + z[i] = ((uint32_t*)idft_out0)[ip]; - - for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) { - z[i] = ((int32_t*)idft_out0)[ip]; - } - - // conjugate output - for (i = 0; i < (Msc_PUSCH>>2); i++) { + // conjugate output + for (i = 0; i < (Msc_PUSCH>>2); i++) { #if defined(__x86_64__) || defined(__i386__) - ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]); + ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]); #elif defined(__arm__) - *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); + *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]); #endif + } } #if defined(__x86_64__) || defined(__i386__) @@ -222,6 +298,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) } + void nr_ulsch_extract_rbs_single(int32_t **rxdataF, NR_gNB_PUSCH *pusch_vars, unsigned char symbol, @@ -268,6 +345,9 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, n = 0; k_prime = 0; + rxF_ext_index = 0; + ul_ch0_ext_index = 0; + ul_ch0_index = 0; if (is_dmrs_symbol == 0) { // @@ -329,7 +409,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, #if defined(__x86_64__)||defined(__i386__) short rb, ch_amp; - unsigned char aatx,aarx; + unsigned char aarx; __m128i *ul_ch128, ch_amp128; // Determine scaling amplitude based the symbol @@ -347,8 +427,7 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, int off = 0; #endif - for (aatx=0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++) { - for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) { + for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) { ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*(off+(nb_rb*NR_NB_SC_PER_RB))]; @@ -377,7 +456,6 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, } } } - } #endif } @@ -394,6 +472,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, short rb; unsigned char aatx, aarx; + char nb_antennas_ue_tx = 1; __m128i *ul_ch128, avg128U; int16_t x = factor2(len); @@ -405,7 +484,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, int off = 0; #endif - for (aatx = 0; aatx < frame_parms->nb_antennas_tx; aatx++) + for (aatx = 0; aatx < nb_antennas_ue_tx; aatx++) for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { //clear average level avg128U = _mm_setzero_si128(); @@ -546,11 +625,12 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, unsigned short rb; unsigned char aatx,aarx; + char nb_antennas_ue_tx = 1; __m128i *ul_ch128,*ul_ch128_2,*ul_ch_mag128,*ul_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; QAM_amp128b = _mm_setzero_si128(); - for (aatx=0; aatxnb_antennas_tx; aatx++) { + for (aatx=0; aatxframe_parms; nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu; @@ -1136,6 +1217,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, bwp_start_subcarrier, rel15_ul); + nr_gnb_measurements(gNB, ulsch_id, harq_pid, symbol); + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = signal_energy_nodc(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol*frame_parms->ofdm_symbol_size], rel15_ul->rb_size*12); @@ -1185,7 +1268,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, avgs = 0; - for (aatx=0;aatxnb_antennas_tx;aatx++) + for (aatx=0;aatxnb_antennas_rx;aarx++) avgs = cmax(avgs,avg[(aatx<<1)+aarx]); @@ -1203,7 +1286,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[ulsch_id]->ul_ch_mag0, gNB->pusch_vars[ulsch_id]->ul_ch_magb0, gNB->pusch_vars[ulsch_id]->rxdataF_comp, - (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, + (nb_antennas_ue_tx>1) ? gNB->pusch_vars[ulsch_id]->rho : NULL, frame_parms, symbol, dmrs_symbol_flag, diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 2d1fdff4be..ba29a2176b 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -390,6 +390,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, if ((xrtmag_dB<(11+dB_fixed(no_corr))) || (dB_fixed(av_corr)<(13+gNB->measurements.n0_power_tot_dB))) //TODO these are temporary threshold based on measurments with the phone no_conf=true; } + gNB->bad_pucch += no_conf; // 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 @@ -1604,7 +1605,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset; // estimate CQI for MAC (from antenna port 0 only) int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset],12*pucch_pdu->prb_size)) - (10*gNB->measurements.n0_power_tot_dB); - int cqi; + int cqi,bit_left; if (SNRtimes10 < -640) cqi=0; else if (SNRtimes10 > 635) cqi=255; else cqi=(640+SNRtimes10)/5; @@ -1628,7 +1629,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uci_pdu->harq.harq_payload[i] = decodedPayload[0] & 255; decodedPayload[0]>>=8; } - uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_harq&7))-1); + bit_left = pucch_pdu->bit_len_harq-((harq_bytes-1)<<3); + uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<>= pucch_pdu->bit_len_harq; } @@ -1642,6 +1644,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, // csi if (pucch_pdu->bit_len_csi_part1>0) { uci_pdu->pduBitmap|=4; + uci_pdu->csi_part1.csi_part1_bit_len=pucch_pdu->bit_len_csi_part1; int csi_part1_bytes=pucch_pdu->bit_len_csi_part1>>3; if ((pucch_pdu->bit_len_csi_part1&7) > 0) csi_part1_bytes++; uci_pdu->csi_part1.csi_part1_payload = (uint8_t*)malloc(csi_part1_bytes); @@ -1651,7 +1654,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & 255; decodedPayload[0]>>=8; } - uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_csi_part1&7))-1); + bit_left = pucch_pdu->bit_len_csi_part1-((csi_part1_bytes-1)<<3); + uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<>= pucch_pdu->bit_len_csi_part1; } 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 6cb0a612e9..76a48f38ae 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -77,9 +77,9 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, // generate pilot nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); - int re_offset = ssb_offset; for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + int re_offset = ssb_offset; pil = (int16_t *)&pilot[0]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -277,9 +277,9 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]); - int re_offset = ssb_offset; for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + int re_offset = ssb_offset; pil = (int16_t *)&pilot[0]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; @@ -456,12 +456,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // 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]) + if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+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); + (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx][ch_offset], + (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p*ue->frame_parms.nb_antennas_rx)+aarx],1); } } } @@ -512,6 +512,13 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, fr = filt16a_r1; + // checking if re-initialization of scrambling IDs is needed (should be done here but scrambling ID for PDCCH is not taken from RRC) +/* if (( != ue->scramblingID_pdcch){ + ue->scramblingID_pdcch=; + nr_gold_pdsch(ue,ue->scramblingID_pdcch); + }*/ + + // generate pilot int pilot[nb_rb_coreset * 3] __attribute__((aligned(16))); nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset); @@ -672,7 +679,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; if (ue->high_speed_flag == 0) - ch_offset = ue->frame_parms.ofdm_symbol_size ; + ch_offset = ue->frame_parms.ofdm_symbol_size; else ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; @@ -690,11 +697,19 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 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); + + // checking if re-initialization of scrambling IDs is needed + if ((ue->dmrs_DownlinkConfig.scramblingID0 != ue->scramblingID[0]) || (ue->dmrs_DownlinkConfig.scramblingID1 != ue->scramblingID[1])){ + ue->scramblingID[0]=ue->dmrs_DownlinkConfig.scramblingID0; + ue->scramblingID[1]=ue->dmrs_DownlinkConfig.scramblingID1; + nr_gold_pdsch(ue,ue->scramblingID); + } + + nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000+p,0,nb_rb_pdsch+rb_offset); if (config_type == pdsch_dmrs_type1){ nushift = (p>>1)&1; - ue->frame_parms.nushift = nushift; + if (p<4) ue->frame_parms.nushift = nushift; switch (delta) { case 0://port 0,1 @@ -734,7 +749,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, } } else {//pdsch_dmrs_type2 nushift = delta; - ue->frame_parms.nushift = nushift; + if (p<6) ue->frame_parms.nushift = nushift; switch (delta) { case 0://port 0,1 fl = filt8_l2;//left interpolation Filter should be fml diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 61fc40ad3f..3f52b29281 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -21,16 +21,17 @@ /*! \file nr_ue_measurements.c * \brief UE measurements routines - * \author R. Knopp, G. Casati + * \author R. Knopp, G. Casati, K. Saaifan * \date 2020 * \version 0.1 * \company Eurecom, Fraunhofer IIS - * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de + * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de, khodr.saaifan@iis.fraunhofer.de * \note * \warning */ #include "executables/softmodem-common.h" +#include "executables/nr-softmodem-common.h" #include "PHY/defs_nr_UE.h" #include "PHY/phy_extern_nr_ue.h" #include "common/utils/LOG/log.h" @@ -45,7 +46,7 @@ //#define DEBUG_MEAS_UE //#define DEBUG_RANK_EST -// Returns the pathloss in dBm for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission +// Returns the pathloss in dB 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 @@ -59,18 +60,17 @@ int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index){ if (get_softmodem_params()->do_ra){ 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))); + pathloss = (int16_t)(referenceSignalPower - ue->measurements.rsrp_dBm[gNB_index]); - 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", + LOG_D(MAC, "In %s: pathloss %d dB, UE RX total gain %d dB, referenceSignalPower %ld dBm/RE (%f mW), RSRP %d dBm (%f mW)\n", __FUNCTION__, pathloss, ue->rx_total_gain_dB, referenceSignalPower, pow(10, referenceSignalPower/10), - rsrp_dBm, - pow(10, rsrp_dBm/10)); + ue->measurements.rsrp_dBm[gNB_index], + pow(10, ue->measurements.rsrp_dBm[gNB_index]/10)); } else { @@ -178,9 +178,9 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, 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; + ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - 10*log10(pow(2, 30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size); - LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", + LOG_I(PHY, "[gNB %d] Slot %d, RSSI %d dBm/RE, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d \n", gNB_id, slot, ue->measurements.rx_rssi_dBm[gNB_id], @@ -258,15 +258,20 @@ void nr_ue_rsrp_measurements(PHY_VARS_NR_UE *ue, 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", + ue->measurements.rsrp_dBm[gNB_id] = 10*log10(ue->measurements.rsrp[gNB_id]) + 30 - 10*log10(pow(2,30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size); + + LOG_D(PHY, "In %s: [UE %d] slot %d SS-RSRP: %d dBm/RE (%d)\n", __FUNCTION__, ue->Mod_id, slot, - 10*log10(ue->measurements.rsrp[gNB_id]) + 30 - ue->rx_total_gain_dB, + ue->measurements.rsrp_dBm[gNB_id], ue->measurements.rsrp[gNB_id]); } +// This function computes the received noise power +// Measurement units: +// - psd_awgn (AWGN power spectral density): dBm/Hz void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t slot){ @@ -279,6 +284,9 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, 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; + double rx_gain = openair0_cfg[0].rx_gain[0]; + double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0]; + 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); @@ -322,10 +330,17 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, 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); + const int psd_awgn = -174; + const int scs = 15000 * (1 << ue->frame_parms.numerology_index); + const int nf_usrp = ue->measurements.n0_power_tot_dB + 3 + 30 - ((int)rx_gain - (int)rx_gain_offset) - 10 * log10(pow(2, 30)) - (psd_awgn + dB_fixed(scs) + dB_fixed(ue->frame_parms.ofdm_symbol_size)); + LOG_D(PHY, "In [%s][slot:%d] NF USRP %d dB\n", __FUNCTION__, slot, 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); + LOG_D(PHY, "In [%s][slot:%d] Noise Level %d (digital level %d dB, noise power spectral density %f dBm/RE)\n", + __FUNCTION__, + slot, + ue->measurements.n0_power_tot, + ue->measurements.n0_power_tot_dB, + ue->measurements.n0_power_tot_dB + 30 - 10*log10(pow(2, 30)) - dB_fixed(ue->frame_parms.ofdm_symbol_size) - ((int)rx_gain - (int)rx_gain_offset)); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index bfec64820b..8176514eb4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -158,7 +158,6 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, if ((reg % reg_bundle_size_L) == 0) r++; } - // 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] = {}; @@ -175,7 +174,6 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, } } - 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); @@ -404,11 +402,12 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, c_rb = 0; for (int rb=0;rb>3] & (1<<(7-(c_rb_by6&7)))) == 0) { - c_rb+=6; - c_rb_by6 = c_rb/6; - } + c_rb+=6; + c_rb_by6 = c_rb/6; + } LOG_DDD("c_rb=%d\n",c_rb); rxF=NULL; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 429bd9a836..d5c0245fdc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -261,7 +261,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); t_nrLDPC_dec_params decParams; t_nrLDPC_dec_params* p_decParams = &decParams; - t_nrLDPC_time_stats procTime; + t_nrLDPC_time_stats procTime = {0}; t_nrLDPC_time_stats* p_procTime =&procTime ; if (!harq_process) { @@ -678,7 +678,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, memcpy(harq_process->b+offset, harq_process->c[r], - Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0)); + 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)); if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 9a31257244..35c4a6e8cb 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -84,8 +84,8 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{ */ //unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}}; - -extern void print_shorts(char *s,int16_t *x); +#define print_ints(s,x) printf("%s %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3]) +#define print_shorts(s,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]) static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext, int **dl_ch_estimates_ext_i, @@ -96,6 +96,16 @@ static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext, int length, int start_point); +uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, + int **dl_ch_mag, + int **dl_ch_magb, + int **dl_ch_estimates_ext, + unsigned short nb_rb, + unsigned char n_rx, + unsigned char mod_order, + int shift, + unsigned char symbol); + static void nr_dlsch_layer_demapping(int16_t **llr_cw, uint8_t Nl, uint8_t mod_order, @@ -113,7 +123,7 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, RX_type_t rx_type, unsigned char harq_pid, unsigned char gNB_id, - unsigned char eNB_id_i, + unsigned char gNB_id_i, unsigned char first_symbol_flag, unsigned char symbol, unsigned short nb_rb, @@ -129,7 +139,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 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 + unsigned char gNB_id_i, uint32_t frame, uint8_t nr_slot_rx, unsigned char symbol, @@ -145,7 +155,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, PHY_NR_MEASUREMENTS *measurements = &ue->measurements; NR_UE_DLSCH_t **dlsch; - int avg[4]; + int avg[16]; // int avg_0[2]; // int avg_1[2]; @@ -173,7 +183,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //int16_t *pllr_symbol_cw1_deint; //uint16_t bundle_L = 2; uint8_t pilots=0; - uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; + uint8_t config_type;// We should not use ue->dmrs_DownlinkConfig.pdsch_dmrs_type; uint16_t n_tx=1, n_rx=1; int32_t median[16]; uint32_t len; @@ -331,90 +341,44 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #endif pilots = ((1<dlDmrsSymbPos)>0 ? 1 : 0; + config_type = dlsch0_harq->dmrsConfigType; - if (frame_parms->nb_antenna_ports_gNB>1 && beamforming_mode==0) { -#ifdef DEBUG_DLSCH_MOD - LOG_I(PHY,"dlsch: using pmi %x (%p)\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0]); -#endif - + if (beamforming_mode==0) {//No beamforming #if UE_TIMING_TRACE 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[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[gNB_id]->pmi_ext, - symbol, - pilots, - start_rb, - nb_rb_pdsch, - 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("\n"); -#endif - - if (rx_type >= rx_IC_single_stream) { - 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, - pdsch_vars[eNB_id_i]->pmi_ext, - symbol, - pilots, - start_rb, - nb_rb_pdsch, - 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[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, - pdsch_vars[eNB_id_i]->pmi_ext, - symbol, - pilots, - start_rb, - nb_rb_pdsch, - 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_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[gNB_id]->pmi_ext, - symbol, - pilots, - config_type, - start_rb + dlsch0_harq->BWPStart, - nb_rb_pdsch, - nr_slot_rx, - ue->high_speed_flag, - frame_parms, - dlsch0_harq->dlDmrsSymbPos); - - } /*else if(beamforming_mode>7) { + if (dlsch0_harq->Nl > 1)//More than or equal 2 layers + nb_rb = nr_dlsch_extract_rbs_multiple(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, + symbol, + pilots, + config_type, + start_rb + dlsch0_harq->BWPStart, + nb_rb_pdsch, + dlsch0_harq->n_dmrs_cdm_groups, + dlsch0_harq->Nl, + frame_parms, + dlsch0_harq->dlDmrsSymbPos); + else// one layer + 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, + symbol, + pilots, + config_type, + start_rb + dlsch0_harq->BWPStart, + nb_rb_pdsch, + dlsch0_harq->n_dmrs_cdm_groups, + 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, gNB_id %d\n",nb_rb,gNB_id); if (nb_rb==0) { LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n"); @@ -437,16 +401,18 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif - n_tx = frame_parms->nb_antenna_ports_gNB; + n_tx = dlsch0_harq->Nl; n_rx = frame_parms->nb_antennas_rx; nr_dlsch_scale_channel(pdsch_vars[gNB_id]->dl_ch_estimates_ext, - frame_parms, - dlsch, - symbol, - pilots, - len, - nb_rb); + frame_parms, + n_tx, + n_rx, + dlsch, + symbol, + pilots, + len, + nb_rb); #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); @@ -462,42 +428,40 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #endif if (first_symbol_flag==1) { if (beamforming_mode==0){ - if (dlsch0_harq->mimo_modedl_ch_estimates_ext, - frame_parms, - avg, - symbol, - len, - nb_rb); - avgs = 0; - for (aatx=0;aatxnb_antenna_ports_gNB;aatx++) - for (aarx=0;aarxnb_antennas_rx;aarx++) - avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext, + frame_parms, + n_tx, + avg, + symbol, + len, + nb_rb); + avgs = 0; + for (aatx=0;aatxnb_antennas_rx+aarx]); + avgs = cmax(avgs,avg[(aatx*frame_parms->nb_antennas_rx)+aarx]); + //LOG_I(PHY, "avgs Power per SC is %d\n", avgs); + median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx]; + } + pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2)+3; + //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh); - 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[gNB_id]->dl_ch_estimates_ext, - median, - n_tx, - n_rx, - 2*len,// subcarriers Re Im - 0); + if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { + nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext, + median, + n_tx, + n_rx, + len, + symbol*nb_rb*12); - for (aatx = 0; aatx < n_tx; ++aatx) - { - for (aarx = 0; aarx < n_rx; ++aarx) - { - avgs = cmax(avgs, median[aatx*n_rx + aarx]); - } - } - - pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; // this might need to be tuned - - } + for (aatx = 0; aatx < n_tx; aatx++) { + for (aarx = 0; aarx < n_rx; aarx++) { + avgs = cmax(avgs, median[aatx*n_rx + aarx]); + } + } + pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; + } } - //#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_slot_rx, @@ -506,22 +470,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[gNB_id]->log2_maxh1, avg[0], avgs); - //LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); - //#endif - - //wait until pdcch is decoded - //proc->channel_level = 1; } - /* - uint32_t wait = 0; - while(proc->channel_level == 0) - { - usleep(1); - wait++; - } - */ - #if T_TRACER if (type == PDSCH) { @@ -546,58 +496,25 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, // Now channel compensation if (dlsch0_harq->mimo_moderxdataF_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[gNB_id]->log2_maxh, - measurements); // log2_maxh+I0_shift - /*if (symbol == 5) { - 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); - } */ + 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, + (n_tx>1) ? pdsch_vars[gNB_id]->rho : NULL, + frame_parms, + n_tx, + symbol, + pilots, + first_symbol_flag, + dlsch0_harq->Qm, + nb_rb, + pdsch_vars[gNB_id]->log2_maxh, + measurements); // log2_maxh+I0_shift + } - /*if ((rx_type==rx_IC_single_stream) && - (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, - pdsch_vars[eNB_id_i]->dl_ch_magb0, - pdsch_vars[eNB_id_i]->rxdataF_comp0, - (aatx>1) ? pdsch_vars[eNB_id_i]->rho : NULL, - frame_parms, - symbol, - first_symbol_flag, - i_mod, - nb_rb, - 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[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 - - dlsch_dual_stream_correlation(frame_parms, - symbol, - nb_rb, - pdsch_vars[gNB_id]->dl_ch_estimates_ext, - pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - 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[gNB_id]->rxdataF_ext, + else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { + 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, @@ -609,40 +526,16 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 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[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[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[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 - } */ - - } + // compute correlation between signal and interference channels (rho12 and rho21) + 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); + } #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); @@ -657,35 +550,50 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, 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[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[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 - } */ + if (frame_parms->nb_antennas_rx > 1) { + if (dlsch0_harq->mimo_moderxdataF_comp0, + (n_tx>1)? pdsch_vars[gNB_id]->rho : NULL, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + n_tx, + n_rx, + symbol, + nb_rb); + if (n_tx == 2)//Apply zero forcing for 2 Tx layers + nr_zero_forcing_rx_2layers(pdsch_vars[gNB_id]->rxdataF_comp0, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + pdsch_vars[gNB_id]->dl_ch_estimates_ext, + nb_rb, + n_rx, + dlsch0_harq->Qm, + pdsch_vars[gNB_id]->log2_maxh, + symbol); } + else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { + 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); } - - //printf("start compute LLR\n"); + } + //printf("start compute LLR\n"); if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { 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; - dl_ch_mag_ptr = pdsch_vars[eNB_id_i]->dl_ch_mag0; + rxdataF_comp_ptr = pdsch_vars[gNB_id_i]->rxdataF_comp0; + dl_ch_mag_ptr = pdsch_vars[gNB_id_i]->dl_ch_mag0; //i_mod should have been passed as a parameter } @@ -747,7 +655,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, rxdataF_comp_ptr, dl_ch_mag_ptr, dlsch0_harq, dlsch1_harq, rx_type, harq_pid, - gNB_id, eNB_id_i, + gNB_id, gNB_id_i, first_symbol_flag, i, nb_rb, round, codeword_TB0, codeword_TB1, @@ -868,10 +776,11 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, int **dl_ch_magb, int **dl_ch_magr, int **rxdataF_comp, - int **rho, + int ***rho, NR_DL_FRAME_PARMS *frame_parms, + uint8_t nb_aatx, unsigned char symbol, - uint8_t pilots, + uint8_t pilots, uint8_t first_symbol_flag, unsigned char mod_order, unsigned short nb_rb, @@ -882,12 +791,12 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, #if defined(__i386) || defined(__x86_64) unsigned short rb; - unsigned char aatx,aarx; + unsigned char aatx,aarx,atx; __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++) { + for (aatx=0; aatxnb_antennas_rx; aarx++) { - 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]; + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + dl_ch_mag128 = (__m128i *)&dl_ch_mag[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + dl_ch_mag128b = (__m128i *)&dl_ch_magb[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; + dl_ch_mag128r = (__m128i *)&dl_ch_magr[(aatx*frame_parms->nb_antennas_rx)+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]; - + rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; for (rb=0; rb2) { @@ -997,10 +905,15 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, // print_ints("c0",&mmtmpD2); // print_ints("c1",&mmtmpD3); rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol); // print_shorts("rx:",rxdataF128); // print_shorts("ch:",dl_ch128); // print_shorts("pack:",rxdataF_comp128); + //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol); + //print_shorts("rx:",(int16_t*)&rxdataF128[0]); + //print_shorts("ch:",(int16_t*)&dl_ch128[0]); + //print_shorts("pack:",(int16_t*)&rxdataF_comp128[0]); // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) @@ -1015,9 +928,9 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); + //print_shorts("rx:",(int16_t*)&rxdataF128[1]); + //print_shorts("ch:",(int16_t*)&dl_ch128[1]); + //print_shorts("pack:",(int16_t*)&rxdataF_comp128[1]); if (pilots==0) { // multiply by conjugated channel @@ -1034,9 +947,9 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); + //print_shorts("rx:",(int16_t*)&rxdataF128[2]); + //print_shorts("ch:",(int16_t*)&dl_ch128[2]); + //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]); dl_ch128+=3; dl_ch_mag128+=3; @@ -1044,107 +957,145 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, 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; } - + 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; + } } } } - if (rho) { + //we compute the Tx correlation matrix for each Rx antenna + //As an example the 2x2 MIMO case requires + //rho[aarx][nb_aatx*nb_aatx] = [cov(H_aarx_0,H_aarx_0) cov(H_aarx_0,H_aarx_1) + // cov(H_aarx_1,H_aarx_0) cov(H_aarx_1,H_aarx_1)], aarx=0,...,nb_antennas_rx-1 + int avg_rho_re[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx]; + int avg_rho_im[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx]; for (aarx=0; aarxnb_antennas_rx; aarx++) { - rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0; rbnb_antennas_rx+aarx][symbol*nb_rb*12]; - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + for (atx=0; atxnb_antennas_rx+aarx][symbol*nb_rb*12]; - //print_shorts("rx:",dl_ch128_2); - //print_shorts("ch:",dl_ch128); - //print_shorts("pack:",rho128); + for (rb=0; rbrx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*nb_rb*12],rb*12); + rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + //print_shorts("rx:",dl_ch128_2+2); + //print_shorts("ch:",dl_ch128+2); + //print_shorts("pack:",rho128+2); + avg_rho_re[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[0]+ + ((int16_t*)&rho128[2])[2] + + ((int16_t*)&rho128[2])[4] + + ((int16_t*)&rho128[2])[6])/16; + + avg_rho_im[aarx][aatx*nb_aatx+atx] +=(((int16_t*)&rho128[2])[1]+ + ((int16_t*)&rho128[2])[3] + + ((int16_t*)&rho128[2])[5] + + ((int16_t*)&rho128[2])[7])/16; + + dl_ch128+=3; + dl_ch128_2+=3; + rho128+=3; + } + if (first_symbol_flag==1) { + //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],rb*12); + avg_rho_re[aarx][aatx*nb_aatx+atx] = 16*avg_rho_re[aarx][aatx*nb_aatx+atx]/(nb_rb*12); + avg_rho_im[aarx][aatx*nb_aatx+atx] = 16*avg_rho_im[aarx][aatx*nb_aatx+atx]/(nb_rb*12); + printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]); + } + } } } } - _mm_empty(); _m_empty(); #elif defined(__arm__) - unsigned short rb; unsigned char aatx,aarx,symbol_mod,pilots=0; @@ -1349,7 +1300,7 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext, int **dl_ch_mag, int **dl_ch_magb, int **rxdataF_comp, - int **rho, + int ***rho, unsigned char n_tx, unsigned char n_rx, unsigned char mod_order, @@ -1486,7 +1437,7 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext, for (aarx=0; aarxnb_antenna_ports_gNB; aatx++) { - for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) + for (aatx=0; aatxnb_antennas_rx; aarx++) { //clear average level avg128D = _mm_setzero_si128(); - // 5 is always a symbol with no pilots for both normal and extended prefix - dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; + dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; for (rb=0;rbnb_antennas_rx)+aarx] =(((int32_t*)&avg128D)[0] + ((int32_t*)&avg128D)[1] + ((int32_t*)&avg128D)[2] + ((int32_t*)&avg128D)[3])/y; @@ -1729,38 +1682,36 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, int norm_pack; __m128i *dl_ch128, norm128D; - for (aatx=0; aatx>2; + length2 = length>>2;//length = number of REs, hence length2=nb_REs*(32/128) in SIMD loop for (ii=0;ii max) - max = norm_pack; + max = norm_pack;//store values more than max if (norm_pack < min) - min = norm_pack; - + min = norm_pack;//store values less than min dl_ch128+=1; } - median[aatx*n_rx + aarx] = (max+min)>>1; - - // printf("Channel level median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]); + median[aatx*n_rx + aarx] = (max+min)>>1; + //printf("Channel level median [%d]: %d max = %d min = %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx],max,min); } - } + } _mm_empty(); _m_empty(); @@ -2100,37 +2051,37 @@ void nr_dlsch_detection_mrc_core(int **rxdataF_comp, //============================================================================================== unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned short pmi, - unsigned char *pmi_ext, - unsigned char symbol, - uint8_t pilots, - uint8_t config_type, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - unsigned char nr_slot_rx, - uint32_t high_speed_flag, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned char symbol, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint8_t n_dmrs_cdm_groups, NR_DL_FRAME_PARMS *frame_parms, - uint16_t dlDmrsSymbPos) { - - + uint16_t dlDmrsSymbPos) +{ unsigned short k,rb; - unsigned char i,aarx; //,nsymb,sss_symb,pss_symb=0,l; + unsigned char nushift,i,aarx; int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; int8_t validDmrsEst = 0; //store last DMRS Symbol index unsigned char j=0; - 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); + if (config_type==pdsch_dmrs_type1) { + AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, + "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); + nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1 + + } else { + AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3, + "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); + nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2 + } for (aarx=0; aarxnb_antennas_rx; aarx++) { @@ -2151,33 +2102,35 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, 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; + 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 {//the symbol contains DMRS j=0; if (config_type==pdsch_dmrs_type1){ - for (i = (1-frame_parms->nushift); i<12; i+=2) { + if (nushift == 0) {//data is multiplexed + for (i = (1-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 {//pdsch_dmrs_type2 + for (i = (2+nushift); i<6; i++) { 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++) { + for (i = (8+nushift); i<12; 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_ext+= j; + rxF_ext+= j; } } @@ -2190,104 +2143,782 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, } } } - - - return(nb_rb_pdsch/frame_parms->nb_antennas_rx); + return(nb_rb_pdsch); } -unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned short pmi, - unsigned char *pmi_ext, - unsigned char symbol, - uint8_t pilots, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - unsigned char nr_slot_rx, - uint32_t high_speed_flag, - NR_DL_FRAME_PARMS *frame_parms, - MIMO_mode_t mimo_mode) { +unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned char symbol, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint8_t n_dmrs_cdm_groups, + uint8_t Nl, + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos) +{ - int prb,nb_rb=0; - unsigned short k; - int i,j,aarx; - int32_t *dl_ch0=NULL,*dl_ch0_ext=NULL,*dl_ch1=NULL,*dl_ch1_ext=NULL,*rxF=NULL,*rxF_ext=NULL; + unsigned short k,rb; + unsigned char nushift,j,i,aarx,aatx; + int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; + int8_t validDmrsEst = 0; //store last DMRS Symbol index - k = frame_parms->first_carrier_offset + 516; //0 + if (config_type==pdsch_dmrs_type1) { + AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, + "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); + nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1 + } else { + AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3, + "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); + nushift = (n_dmrs_cdm_groups -1)<<1;//delta in Table 7.4.1.1.2-2 + } + + validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol); for (aarx=0; aarxnb_antennas_rx; aarx++) { - if (high_speed_flag==1) { - dl_ch0 = &dl_ch_estimates[aarx][symbol*(frame_parms->ofdm_symbol_size)]; - dl_ch1 = &dl_ch_estimates[2+aarx][symbol*(frame_parms->ofdm_symbol_size)]; - } else { - dl_ch0 = &dl_ch_estimates[aarx][0]; - dl_ch1 = &dl_ch_estimates[2+aarx][0]; - } + k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb; + if (k>frame_parms->ofdm_symbol_size) + k = k-frame_parms->ofdm_symbol_size; - //pmi_loc = pmi_ext; + rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)]; + rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; - // pointers to extracted RX signals and channel estimates - rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)]; - dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(nb_rb_pdsch*12)]; - dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(nb_rb_pdsch*12)]; + for (aatx=0; aatxN_RB_DL; prb++) { - //skip_half=0; + dl_ch0 = &dl_ch_estimates[(aatx*frame_parms->nb_antennas_rx)+aarx][(validDmrsEst*(frame_parms->ofdm_symbol_size))]; + dl_ch0_ext = &dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*(nb_rb_pdsch*NR_NB_SC_PER_RB)]; - if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs - - // For second half of RBs skip DC carrier - if (k>=frame_parms->ofdm_symbol_size) { - rxF = &rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))]; - k=k-(frame_parms->ofdm_symbol_size); + for (rb = 0; rb < nb_rb_pdsch; rb++) + { + if (pilots==0) {//data symbol only + if (aatx==0) {//Extract Rx signal only + memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); + rxF_ext+=12; + } + memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));//Extract Channel Estimate + dl_ch0_ext+=12; + } + else {//the symbol contains DMRS + j=0; + if (config_type==pdsch_dmrs_type1) { + if (nushift == 0) {//data is multiplexed + for (i = (1-nushift); i<12; i+=2) { + if (aatx==0) rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+=6; + if (aatx==0) rxF_ext+=6; + } + } + else {//pdsch_dmrs_type2 + for (i = (2+nushift); i<6; i++) { + if (aatx==0) rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + for (i = (8+nushift); i<12; i++) { + if (aatx==0) rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+= j; + if (aatx==0) rxF_ext+= j; + } } - /* - if (mimo_mode <= PUSCH_PRECODING1) - *pmi_loc = (pmi>>((prb>>2)<<1))&3; - else - *pmi_loc=(pmi>>prb)&1;*/ - - // *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); - // pmi_loc++; - - - if (pilots == 0) { - - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int)); - memcpy(rxF_ext,rxF,12*sizeof(int)); - dl_ch0_ext +=12; - dl_ch1_ext +=12; - rxF_ext +=12; - } else { // pilots==1 - j=0; - for (i=0; i<12; i++) { - if ((i&1)!=frame_parms->nushift) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j++]=dl_ch1[i]; - } - } - dl_ch0_ext+=6; - dl_ch1_ext+=6; - rxF_ext+=6; - } // pilots==1 - - dl_ch0+=12; - dl_ch1+=12; + dl_ch0+=12; + if (aatx==0) { rxF+=12; k+=12; - } - } // for prb - } // for aarx - return(nb_rb/frame_parms->nb_antennas_rx); + if (k>=frame_parms->ofdm_symbol_size) { + k=k-(frame_parms->ofdm_symbol_size); + rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; + } + } + }//rb + }//aatx + }//aarx + return(nb_rb_pdsch); } +void nr_dlsch_detection_mrc(int **rxdataF_comp, + int ***rho, + int **dl_ch_mag, + int **dl_ch_magb, + short n_tx, + short n_rx, + unsigned char symbol, + unsigned short nb_rb) { +#if defined(__x86_64__)||defined(__i386__) + unsigned char aatx, aarx; + int i; + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b; + + if (n_rx>1) { + for (aatx=0; aatxN_RB_DL*12]; + rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12]; + for (i=0; i=2){ + // (1/2^log2_maxh)*conj_H_00xH_00: (1/(64*2))conjH_00*H_00*2^15 + nr_conjch0_mult_ch1(ch00, + ch00, + conjch00_ch00, + nb_rb, + shift); + // (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15 + nr_conjch0_mult_ch1(ch10, + ch10, + conjch10_ch10, + nb_rb, + shift); + // conj_H_00xH_01 + nr_conjch0_mult_ch1(ch00, + ch01, + conjch00_ch01, + nb_rb, + shift); // this shift is equal to the channel level log2_maxh + // conj_H_10xH_11 + nr_conjch0_mult_ch1(ch10, + ch11, + conjch10_ch11, + nb_rb, + shift); + // conj_H_01xH_01 + nr_conjch0_mult_ch1(ch01, + ch01, + conjch01_ch01, + nb_rb, + shift); + // conj_H_11xH_11 + nr_conjch0_mult_ch1(ch11, + ch11, + conjch11_ch11, + nb_rb, + shift); + // conj_H_01xH_00 + nr_conjch0_mult_ch1(ch01, + ch00, + conjch01_ch00, + nb_rb, + shift); + // conj_H_11xH_10 + nr_conjch0_mult_ch1(ch11, + ch10, + conjch11_ch10, + nb_rb, + shift); + } + if (n_rx==4){ + // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2*16))conjH_20*H_20*2^15 + nr_conjch0_mult_ch1(ch20, + ch20, + conjch20_ch20, + nb_rb, + shift); + + // (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15 + nr_conjch0_mult_ch1(ch30, + ch30, + conjch30_ch30, + nb_rb, + shift); + + // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 + nr_conjch0_mult_ch1(ch20, + ch21, + conjch20_ch21, + nb_rb, + shift); + + nr_conjch0_mult_ch1(ch30, + ch31, + conjch30_ch31, + nb_rb, + shift); + + nr_conjch0_mult_ch1(ch21, + ch21, + conjch21_ch21, + nb_rb, + shift); + + nr_conjch0_mult_ch1(ch31, + ch31, + conjch31_ch31, + nb_rb, + shift); + + // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 + nr_conjch0_mult_ch1(ch21, + ch20, + conjch21_ch20, + nb_rb, + shift); + + nr_conjch0_mult_ch1(ch31, + ch30, + conjch31_ch30, + nb_rb, + shift); + + nr_construct_HhH_elements(conjch00_ch00, + conjch01_ch01, + conjch11_ch11, + conjch10_ch10,// + conjch20_ch20, + conjch21_ch21, + conjch30_ch30, + conjch31_ch31, + conjch00_ch01, + conjch01_ch00, + conjch10_ch11, + conjch11_ch10,// + conjch20_ch21, + conjch21_ch20, + conjch30_ch31, + conjch31_ch30, + af_mf_00, + af_mf_01, + af_mf_10, + af_mf_11, + nb_rb, + symbol); + } + if (n_rx==2){ + nr_construct_HhH_elements(conjch00_ch00, + conjch01_ch01, + conjch11_ch11, + conjch10_ch10,// + NULL, + NULL, + NULL, + NULL, + conjch00_ch01, + conjch01_ch00, + conjch10_ch11, + conjch11_ch10,// + NULL, + NULL, + NULL, + NULL, + af_mf_00, + af_mf_01, + af_mf_10, + af_mf_11, + nb_rb, + symbol); + } + //det_HhH = ad -bc + nr_det_HhH(af_mf_00,//a + af_mf_01,//b + af_mf_10,//c + af_mf_11,//d + determ_fin, + nb_rb, + symbol); + /* 2- Compute the channel matrix inversion ********************************** + * + * |(conj_H_00xH_00+conj_H_10xH_10) (conj_H_00xH_01+conj_H_10xH_11)| + * A= | | + * |(conj_H_01xH_00+conj_H_11xH_10) (conj_H_01xH_01+conj_H_11xH_11)| + * + * + * + *inv(A) =(1/det)*[d -b + * -c a] + * + * + **************************************************************************/ + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128b_0,*dl_ch_mag128_1,*dl_ch_mag128b_1,*determ_fin_128; + __m128i mmtmpD2,mmtmpD3,mmtmpD0,mmtmpD1,QAM_amp128,QAM_amp128b; + __m128i *after_mf_a_128,*after_mf_b_128, *after_mf_c_128, *after_mf_d_128; + + determ_fin_128 = (__m128i *)&determ_fin[0]; + + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12];//aatx=0 @ aarx =0 + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12];//aatx=1 @ aarx =0 + + dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][symbol*nb_rb*12]; + dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[n_rx][symbol*nb_rb*12]; + dl_ch_mag128b_0 = (__m128i *)&dl_ch_magb[0][symbol*nb_rb*12]; + dl_ch_mag128b_1 = (__m128i *)&dl_ch_magb[n_rx][symbol*nb_rb*12]; + + after_mf_a_128 = (__m128i *)af_mf_00; + after_mf_b_128 = (__m128i *)af_mf_01; + after_mf_c_128 = (__m128i *)af_mf_10; + after_mf_d_128 = (__m128i *)af_mf_11; + + QAM_amp128b = _mm_setzero_si128(); + + if (mod_order == 4) { + QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) + QAM_amp128b = _mm_setzero_si128(); + } else if (mod_order == 6) { + QAM_amp128 = _mm_set1_epi16(QAM64_n1); // + QAM_amp128b = _mm_set1_epi16(QAM64_n2); + } + + for (int rb=0; rb<3*nb_rb; rb++) { + if (mod_order>2) { + // get channel determ (da -bc) if not QPSK + mmtmpD0 = _mm_packs_epi32(determ_fin_128[0],determ_fin_128[0]);//convert 32 bits to 16 bits + + dl_ch_mag128_0[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b_0[0] = dl_ch_mag128_0[0]; + + dl_ch_mag128_0[0] = _mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128); + dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);//aatx=0 @ aarx =0 + dl_ch_mag128_1[0] = dl_ch_mag128_0[0];//aatx=1 @ aarx =0 + + dl_ch_mag128b_0[0] = _mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b); + dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1);//aatx=0 @ aarx = + dl_ch_mag128b_1[0] = dl_ch_mag128b_0[0];//aatx=1 @ aarx =0 + + if ((rb==0)&&(symbol==1)) { + printf("\n Signal mag after ZF \n"); + print_shorts("mag layer 1:",(int16_t*)&dl_ch_mag128_0[0]); + print_shorts("mag layer 2:",(int16_t*)&dl_ch_mag128_1[0]); + print_shorts("magb layer 1:",(int16_t*)&dl_ch_mag128b_0[0]); + print_shorts("magb layer 2:",(int16_t*)&dl_ch_mag128b_1[0]); + } + } + // multiply by channel Inv + //rxdataF_zf128_0 = rxdataF_comp128_0*d - b*rxdataF_comp128_1 + //rxdataF_zf128_1 = rxdataF_comp128_1*a - c*rxdataF_comp128_0 + mmtmpD2 = nr_inv_comp_muli(rxdataF_comp128_0[0],//x + after_mf_d_128[0]);//y + mmtmpD3 = nr_inv_comp_muli(rxdataF_comp128_1[0],//x + after_mf_b_128[0]);//y + //mmtmpD2[0] - mmtmpD3[0] + //rxdataF_zf128_0 + mmtmpD0 = _mm_sub_epi16(mmtmpD2, mmtmpD3); + + mmtmpD2 = nr_inv_comp_muli(rxdataF_comp128_1[0],//x + after_mf_a_128[0]);//y + mmtmpD3 = nr_inv_comp_muli(rxdataF_comp128_0[0],//x + after_mf_c_128[0]);//y + //mmtmpD2[0] - mmtmpD3[0] + //rxdataF_zf128_1 + mmtmpD1 = _mm_sub_epi16(mmtmpD2, mmtmpD3); + + rxdataF_comp128_0[0] = mmtmpD0; + rxdataF_comp128_1[0] = mmtmpD1; + + /*if ((rb==0)&&(symbol==1)) { + printf("\n Rx signal after ZF \n"); + print_shorts("Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]); + print_shorts("Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]); + }*/ + + determ_fin_128 += 1; + dl_ch_mag128_0 += 1; + dl_ch_mag128b_0 += 1; + dl_ch_mag128_1 += 1; + dl_ch_mag128b_1 += 1; + rxdataF_comp128_0 += 1; + rxdataF_comp128_1 += 1; + after_mf_a_128 += 1; + after_mf_b_128 += 1; + after_mf_c_128 += 1; + after_mf_d_128 += 1; + } + _mm_empty(); + _m_empty(); + return(0); +} static void nr_dlsch_layer_demapping(int16_t **llr_cw, uint8_t Nl, @@ -2327,7 +2958,7 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, RX_type_t rx_type, unsigned char harq_pid, unsigned char gNB_id, - unsigned char eNB_id_i, + unsigned char gNB_id_i, unsigned char first_symbol_flag, unsigned char symbol, unsigned short nb_rb, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 13270c5c4b..bfef89ea85 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -289,8 +289,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames) proc, i, 0, - is*fp->samples_per_frame+ue->ssb_offset, - 0); + is*fp->samples_per_frame+ue->ssb_offset); #ifdef DEBUG_INITIAL_SYNCH LOG_I(PHY,"Calling sss detection (normal CP)\n"); @@ -317,7 +316,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames) ue->init_sync_frame = is; } - nr_gold_pdcch(ue,0, 2); /* int nb_prefix_samples0 = fp->nb_prefix_samples0; fp->nb_prefix_samples0 = fp->nb_prefix_samples; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index e33693ce0e..ef884512fd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -60,16 +60,15 @@ uint16_t nr_pbch_extract(int **rxdataF, uint8_t i,j,aarx; int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; 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; - rx_offset=(rx_offset)%(frame_parms->ofdm_symbol_size); AssertFatal(symbol>=1 && symbol<5, "symbol %d illegal for PBCH extraction\n", symbol); for (aarx=0; aarxnb_antennas_rx; aarx++) { + unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; + rx_offset = (rx_offset)%(frame_parms->ofdm_symbol_size); + rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size]; rxF_ext = &rxdataF_ext[aarx][symbol*20*12]; #ifdef DEBUG_PBCH @@ -590,7 +589,9 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, frame_parms->ssb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i)); } - ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms); + ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,i_ssb); + if (frame_parms->half_frame_bit) + ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot; uint8_t frame_number_4lsb = 0; for (int i=0; i<4; i++) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 3ab88dac0a..2c4c0b9e14 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -130,6 +130,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ #endif not_found = 1; + nr_fill_du(N_ZC,prach_root_sequence_map); preamble_index0 = preamble_index; // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this // preamble index and find the corresponding cyclic shift @@ -244,86 +245,82 @@ 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) { - if (fp->threequarter_fs == 0) { - //40 MHz @ 61.44 Ms/s - //50 MHz @ 61.44 Ms/s + switch(fp->samples_per_subframe) { + case 15360: + // 10, 15 MHz @ 15.36 Ms/s if (prach_sequence_length == 0) { if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) - dftlen = 49152; + dftlen = 12288; if (prach_fmt_id == 3) - dftlen = 12288; - } // 839 sequence - else { - switch (mu){ - case 1: - dftlen = 2048; - break; - default: - AssertFatal(1 == 0, "Shouldn't get here\n"); - break; - } + dftlen = 3072; + } else { // 839 sequence + dftlen = 512; } - } else { // threequarter sampling - // 40 MHz @ 46.08 Ms/s + break; + + case 30720: + // 20, 25, 30 MHz @ 30.72 Ms/s + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 24576; + if (prach_fmt_id == 3) + dftlen = 6144; + } else { // 839 sequence + dftlen = 1024; + } + break; + + case 46080: + // 40 MHz @ 46.08 Ms/s if (prach_sequence_length == 0) { - AssertFatal(fp->N_RB_UL <= 107, "cannot do 108..136 PRBs with 3/4 sampling\n"); if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) dftlen = 36864; if (prach_fmt_id == 3) dftlen = 9216; - } else { - switch (mu){ - case 1: - dftlen = 1536; - break; - default: - AssertFatal(1 == 0, "Shouldn't get here\n"); - break; - } - } // short format - } // 3/4 sampling - } // <=50 MHz BW - else if (fp->N_RB_UL <= 273) { - if (fp->threequarter_fs == 0) { - //80,90,100 MHz @ 122.88 Ms/s + } else { // 839 sequence + dftlen = 1536; + } + break; + + case 61440: + // 40, 50, 60 MHz @ 61.44 Ms/s + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 49152; + if (prach_fmt_id == 3) + dftlen = 12288; + } else { // 839 sequence + dftlen = 2048; + } + break; + + case 92160: + // 50, 60, 70, 80, 90 MHz @ 92.16 Ms/s + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 73728; + if (prach_fmt_id == 3) + dftlen = 18432; + } else { // 839 sequence + dftlen = 3072; + } + break; + + case 122880: + // 70, 80, 90, 100 MHz @ 122.88 Ms/s if (prach_sequence_length == 0) { if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) dftlen = 98304; if (prach_fmt_id == 3) dftlen = 24576; + } else { // 839 sequence + dftlen = 4096; } - } else { // threequarter sampling - switch (mu){ - case 1: - dftlen = 4096; - break; - default: - AssertFatal(1 == 0, "Shouldn't get here\n"); - break; - } + break; + + default: + AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); } - } else { - AssertFatal(fp->N_RB_UL <= 217, "cannot do more than 217 PRBs with 3/4 sampling\n"); - // 80 MHz @ 92.16 Ms/s - if (prach_sequence_length == 0) { - if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) - dftlen = 73728; - if (prach_fmt_id == 3) - dftlen = 18432; - } else { - switch (mu){ - case 1: - dftlen = 3072; - break; - default: - AssertFatal(1 == 0, "Shouldn't get here\n"); - break; - } - } - } } else if (mu==3) { if (fp->threequarter_fs) @@ -425,15 +422,16 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ uint8_t use_extended_prach_prefix = 0; if(fp->numerology_index == 0) { if (prachStartSymbol == 0 || prachStartSymbol == 7) - use_extended_prach_prefix = 1; + use_extended_prach_prefix = 1; } else { if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) - use_extended_prach_prefix = 1; + use_extended_prach_prefix = 1; } - - if (fp->N_RB_UL <= 34) { //32 PRB case 61.44Msps - if (fp->threequarter_fs == 0) { + + if (mu == 3) { + switch (fp->samples_per_subframe) { + case 61440: // 32 PRB case, 61.44 Msps Ncp<<=1; //to account for 61.44Mbps // This is after cyclic prefix prach2 = prach+(Ncp<<1); //times 2 for complex samples @@ -491,13 +489,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ 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) { + break; + + case 122880: // 66 PRB case, 122.88 Msps Ncp<<=2; //to account for 122.88Mbps // This is after cyclic prefix prach2 = prach+(Ncp<<1); //times 2 for complex samples @@ -555,13 +549,211 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (1024*12)+Ncp; } } + break; + + default: + AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); } - 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; //to account for 61.44Mbps + } else if (mu == 1) { + switch (fp->samples_per_subframe) { + case 15360: // full sampling @ 15.36 Ms/s + Ncp = Ncp/2; // to account for 15.36 Ms/s + // This is after cyclic prefix + prach2 = prach+(2*Ncp); // times 2 for complex samples + if (prach_sequence_length == 0){ + if (prach_fmt_id == 0) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s + idft(IDFT_12288,prachF,prach2,1); + // here we have | empty | Prach12288 | + memmove(prach,prach+(12288<<1),(Ncp<<2)); + // here we have | Prefix | Prach12288 | + prach_len = 12288+Ncp; + } else if (prach_fmt_id == 1) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s + idft(IDFT_12288,prachF,prach2,1); + // here we have | empty | Prach12288 | empty12288 | + memmove(prach2+(12288<<1),prach2,(12288<<2)); + // here we have | empty | Prach12288 | Prach12288 | + memmove(prach,prach+(12288<<2),(Ncp<<2)); + // here we have | Prefix | Prach12288 | Prach12288 | + prach_len = (12288*2)+Ncp; + } else if (prach_fmt_id == 2) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s + idft(IDFT_12288,prachF,prach2,1); + // here we have | empty | Prach12288 | empty12288 | empty12288 | empty12288 | + memmove(prach2+(12288<<1),prach2,(12288<<2)); + // here we have | empty | Prach12288 | Prach12288 | empty12288 | empty12288 | + memmove(prach2+(12288<<2),prach2,(12288<<3)); + // here we have | empty | Prach12288 | Prach12288 | Prach12288 | Prach12288 | + memmove(prach,prach+(12288<<3),(Ncp<<2)); + // here we have | Prefix | Prach12288 | Prach12288 | Prach12288 | Prach12288 | + prach_len = (12288*4)+Ncp; + } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s, 3072 samples @ 15.36 Ms/s + idft(IDFT_3072,prachF,prach2,1); + // here we have | empty | Prach3072 | empty3072 | empty3072 | empty3072 | + memmove(prach2+(3072<<1),prach2,(3072<<2)); + // here we have | empty | Prach3072 | Prach3072 | empty3072 | empty3072 | + memmove(prach2+(3072<<2),prach2,(3072<<3)); + // here we have | empty | Prach3072 | Prach3072 | Prach3072 | Prach3072 | + memmove(prach,prach+(3072<<3),(Ncp<<2)); + // here we have | Prefix | Prach3072 | Prach3072 | Prach3072 | Prach3072 | + prach_len = (3072*4)+Ncp; + } + } else { // short PRACH sequence + if (use_extended_prach_prefix) + Ncp += 8; // 16*kappa, kappa=0.5 for 15.36 Ms/s + prach2 = prach+(2*Ncp); // times 2 for complex samples + if (prach_fmt_id == 9) { + idft(IDFT_512,prachF,prach2,1); + // here we have | empty | Prach512 | + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have | Prefix | Prach512 | + prach_len = (512*1)+Ncp; + } else if (prach_fmt_id == 4 || prach_fmt_id == 7) { + idft(IDFT_512,prachF,prach2,1); + // here we have | empty | Prach512 | empty512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have | empty | Prach512 | Prach512 | + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have | Prefix | Prach512 | Prach512 | + prach_len = (512*2)+Ncp; + } else if (prach_fmt_id == 5) { // 4x512 + idft(IDFT_512,prachF,prach2,1); + // here we have | empty | Prach512 | empty512 | empty512 | empty512 | + 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 | Prach512 | Prach512 | Prach512 | + prach_len = (512*4)+Ncp; + } else if (prach_fmt_id == 6) { // 6x512 + idft(IDFT_512,prachF,prach2,1); + // here we have | empty | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | + 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 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | + prach_len = (512*6)+Ncp; + } else if (prach_fmt_id == 8) { // 12x512 + idft(IDFT_512,prachF,prach2,1); + // here we have | empty | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have | empty | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | + memmove(prach2+(512<<2),prach2,(512<<3)); + // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | + memmove(prach2+(512<<3),prach2,(512<<3)); + // here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | + 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; + } + } + break; + + case 30720: // full sampling @ 30.72 Ms/s + Ncp = Ncp*1; // to account for 30.72 Ms/s + // This is after cyclic prefix + prach2 = prach+(2*Ncp); // times 2 for complex samples + if (prach_sequence_length == 0){ + if (prach_fmt_id == 0) { // 24576 samples @ 30.72 Ms/s + idft(IDFT_24576,prachF,prach2,1); + // here we have | empty | Prach24576 | + memmove(prach,prach+(24576<<1),(Ncp<<2)); + // here we have | Prefix | Prach24576 | + prach_len = 24576+Ncp; + } else if (prach_fmt_id == 1) { // 24576 samples @ 30.72 Ms/s + idft(IDFT_24576,prachF,prach2,1); + // here we have | empty | Prach24576 | empty24576 | + memmove(prach2+(24576<<1),prach2,(24576<<2)); + // here we have | empty | Prach24576 | Prach24576 | + memmove(prach,prach+(24576<<2),(Ncp<<2)); + // here we have | Prefix | Prach24576 | Prach24576 | + prach_len = (24576*2)+Ncp; + } else if (prach_fmt_id == 2) { // 24576 samples @ 30.72 Ms/s + idft(IDFT_24576,prachF,prach2,1); + // here we have | empty | Prach24576 | empty24576 | empty24576 | empty24576 | + memmove(prach2+(24576<<1),prach2,(24576<<2)); + // here we have | empty | Prach24576 | Prach24576 | empty24576 | empty24576 | + memmove(prach2+(24576<<2),prach2,(24576<<3)); + // here we have | empty | Prach24576 | Prach24576 | Prach24576 | Prach24576 | + memmove(prach,prach+(24576<<3),(Ncp<<2)); + // here we have | Prefix | Prach24576 | Prach24576 | Prach24576 | Prach24576 | + prach_len = (24576*4)+Ncp; + } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s + idft(IDFT_6144,prachF,prach2,1); + // here we have | empty | Prach6144 | empty6144 | empty6144 | empty6144 | + memmove(prach2+(6144<<1),prach2,(6144<<2)); + // here we have | empty | Prach6144 | Prach6144 | empty6144 | empty6144 | + memmove(prach2+(6144<<2),prach2,(6144<<3)); + // here we have | empty | Prach6144 | Prach6144 | Prach6144 | Prach6144 | + memmove(prach,prach+(6144<<3),(Ncp<<2)); + // here we have | Prefix | Prach6144 | Prach6144 | Prach6144 | Prach6144 | + prach_len = (6144*4)+Ncp; + } + } else { // short PRACH sequence + if (use_extended_prach_prefix) + Ncp += 16; // 16*kappa, kappa=1 for 30.72Msps + prach2 = prach+(2*Ncp); // times 2 for complex samples + if (prach_fmt_id == 9) { + idft(IDFT_1024,prachF,prach2,1); + // here we have | empty | Prach1024 | + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have | Prefix | Prach1024 | + prach_len = (1024*1)+Ncp; + } else if (prach_fmt_id == 4 || prach_fmt_id == 7) { + idft(IDFT_1024,prachF,prach2,1); + // here we have | empty | Prach1024 | empty1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have | empty | Prach1024 | Prach1024 | + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have | Prefix | Prach1024 | Prach1024 | + prach_len = (1024*2)+Ncp; + } else if (prach_fmt_id == 5) { // 4x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | + 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 | Prach1024 | Prach1024 | Prach1024 | + prach_len = (1024*4)+Ncp; + } else if (prach_fmt_id == 6) { // 6x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | + 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 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | + prach_len = (1024*6)+Ncp; + } else if (prach_fmt_id == 8) { // 12x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have | empty | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<2),prach2,(1024<<3)); + // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | + memmove(prach2+(1024<<3),prach2,(1024<<3)); + // here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | + 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; + } + } + break; + + case 61440: // full sampling @ 61.44 Ms/s + Ncp = Ncp*2; // to account for 61.44 Ms/s // This is after cyclic prefix prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_sequence_length == 0){ @@ -587,7 +779,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(49152<<3),(Ncp<<2)); // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152 prach_len = (49152*4)+Ncp; - } else if (prach_fmt_id == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s + } else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s idft(IDFT_12288,prachF,prach2,1); memmove(prach2+(12288<<1),prach2,(12288<<2)); // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288 @@ -649,7 +841,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (2048*12)+Ncp; } } - } else { // threequarter sampling @ 46.08 Ms/s + break; + + case 46080: // threequarter sampling @ 46.08 Ms/s Ncp = (Ncp*3)/2; prach2 = prach+(Ncp<<1); if (prach_sequence_length == 0){ @@ -738,9 +932,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (1536*12)+Ncp; } } - } - } 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 + break; + + case 122880: // full sampling @ 122.88 Ms/s Ncp<<=2; //to account for 122.88Mbps // This is after cyclic prefix prach2 = prach+(Ncp<<1); //times 2 for complex samples @@ -828,7 +1022,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (4096*12)+Ncp; } } - } else { // three quarter sampling @ 92.16 Ms/s + break; + + case 92160: // three quarter sampling @ 92.16 Ms/s Ncp = (Ncp*3); //to account for 92.16 Msps prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_sequence_length == 0){ @@ -915,6 +1111,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (3072*12)+Ncp; } } + break; + + default: + AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); } } 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 91274b908a..1e7e10def7 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -686,11 +686,8 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms, 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 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. @@ -698,67 +695,61 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms, @param dl_ch_estimates Channel estimates of current slot @param rxdataF_ext FFT output for RBs in this allocation @param dl_ch_estimates_ext Channel estimates for RBs in this allocation - @param pmi subband Precoding matrix indicator - @param pmi_ext Extracted PMI for chosen RBs @param rb_alloc RB allocation vector @param symbol Symbol to extract - @param nr_slot_rx Slot number - @param high_speed_flag + @param n_dmrs_cdm_groups @param frame_parms Pointer to frame descriptor */ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, int **dl_ch_estimates, int **rxdataF_ext, int **dl_ch_estimates_ext, - unsigned short pmi, - unsigned char *pmi_ext, unsigned char symbol, 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, + unsigned short nb_rb_pdsch, + uint8_t n_dmrs_cdm_groups, NR_DL_FRAME_PARMS *frame_parms, uint16_t dlDmrsSymbPos); -/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF, +/** \fn dlsch_extract_rbs_multiple(int32_t **rxdataF, int32_t **dl_ch_estimates, int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, - uint16_t pmi, - uint8_t *pmi_ext, - uint32_t *rb_alloc, - uint8_t symbol, - NR_DL_FRAME_PARMS *frame_parms) + unsigned char symbol + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint8_t n_dmrs_cdm_groups, + uint8_t Nl, + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos) \brief This function extracts the received resource blocks, both channel estimates and data symbols, - for the current allocation and for dual antenna eNB transmission. + for the current allocation and for multiple layer antenna gNB transmission. @param rxdataF Raw FFT output of received signal @param dl_ch_estimates Channel estimates of current slot @param rxdataF_ext FFT output for RBs in this allocation @param dl_ch_estimates_ext Channel estimates for RBs in this allocation - @param pmi subband Precoding matrix indicator - @param pmi_ext Extracted PMI for chosen RBs - @param rb_alloc RB allocation vector + @param Nl nb of antenna layers @param symbol Symbol to extract - @param nr_slot_rx Slot index - @param high_speed_flag + @param n_dmrs_cdm_groups @param frame_parms Pointer to frame descriptor */ -unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, - unsigned short pmi, - unsigned char *pmi_ext, - unsigned char symbol, - uint8_t pilots, - unsigned short start_rb, - unsigned short nb_rb_pdsch, - unsigned char nr_slot_rx, - uint32_t high_speed_flag, - NR_DL_FRAME_PARMS *frame_parms, - MIMO_mode_t mimo_mode); +unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned char symbol, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_rb_pdsch, + uint8_t n_dmrs_cdm_groups, + uint8_t Nl, + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos); /** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF, int32_t **dl_bf_ch_estimates, @@ -812,8 +803,9 @@ void nr_dlsch_channel_compensation(int32_t **rxdataF_ext, int32_t **dl_ch_magb, int32_t **dl_ch_magr, int32_t **rxdataF_comp, - int32_t **rho, + int32_t ***rho, NR_DL_FRAME_PARMS *frame_parms, + uint8_t nb_aatx, uint8_t symbol, uint8_t start_symbol, uint8_t first_symbol_flag, @@ -827,7 +819,7 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext, int **dl_ch_mag, int **dl_ch_magb, int **rxdataF_comp, - int **rho, + int ***rho, unsigned char n_tx, unsigned char n_rx, unsigned char mod_order, @@ -898,6 +890,15 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, int length, int start_point); +void nr_dlsch_detection_mrc(int **rxdataF_comp, + int ***rho, + int **dl_ch_mag, + int **dl_ch_magb, + short n_tx, + short n_rx, + unsigned char symbol, + unsigned short nb_rb); + void nr_dlsch_detection_mrc_core(int **rxdataF_comp, int **rxdataF_comp_i, int **rho, @@ -971,6 +972,7 @@ void dlsch_channel_compensation_TM34(NR_DL_FRAME_PARMS *frame_parms, */ void nr_dlsch_channel_level(int **dl_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, + uint8_t n_tx, int32_t *avg, uint8_t symbol, uint32_t len, @@ -1002,6 +1004,8 @@ void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext, void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, + uint8_t n_tx, + uint8_t n_rx, NR_UE_DLSCH_t **dlsch_ue, uint8_t symbol, uint8_t start_symbol, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 464bcfcfba..aa32ecc8c9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -105,6 +105,8 @@ typedef struct { uint8_t O_ACK; /// Index of current HARQ round for this ULSCH uint8_t round; + /// Last Ndi for this harq process + uint8_t ndi; /// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8) unsigned char *a; /// Pointer to the payload + CRC diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c index 7cf64b28bb..76fc5f298f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c @@ -78,13 +78,15 @@ void nr_rf_card_config(openair0_config_t *openair0_cfg, 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]); + if (i < openair0_cfg->rx_num_channels) { + 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 d9bea8a3ac..1a39def26b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -202,7 +202,6 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, for (i=0; iharq_processes[i]->round=0; } - return(ulsch); } } @@ -257,7 +256,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, Ilbrm = 0; Tbslbrm = 950984; //max tbs Coderate = 0.0; - harq_process->round = nr_rv_round_map_ue[harq_process->pusch_pdu.pusch_data.rv_index]; /////////// ///////////////////////////////////////////////////////////////////////////////////////// @@ -267,8 +265,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, LOG_D(PHY,"ulsch coding nb_rb %d, Nl = %d\n", nb_rb, harq_process->pusch_pdu.nrOfLayers); LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order); - // if (harq_process->Ndi == 1) { // this is a new packet - if (harq_process->round == 0) { // this is a new packet + if (harq_process->ndi != harq_process->pusch_pdu.pusch_data.new_data_indicator) { // this is a new packet #ifdef DEBUG_ULSCH_CODING printf("encoding thinks this is a new packet \n"); #endif @@ -415,7 +412,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, /////////// /////////////////////////////////////////////////////////////////////////////// - + harq_process->ndi = harq_process->pusch_pdu.pusch_data.new_data_indicator; } F = harq_process->F; Kr = harq_process->K; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 208901f289..3d8c975a5c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -496,13 +496,19 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; for(ap = 0; ap < Nl; ap++) { for (int s=0;s (%d.%d)\n", - s,s+symb_offset,frame_parms->symbol_rotation[2*(s+symb_offset)],frame_parms->symbol_rotation[1+(2*(s+symb_offset))]); - rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s], - &frame_parms->symbol_rotation[2*(s+symb_offset)], - (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s], - frame_parms->ofdm_symbol_size, - 15); + + LOG_D(PHY,"In %s: rotating txdataF symbol %d (%d) => (%d.%d)\n", + __FUNCTION__, + s, + s + symb_offset, + frame_parms->symbol_rotation[1][2 * (s + symb_offset)], + frame_parms->symbol_rotation[1][1 + (2 * (s + symb_offset))]); + + rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], + &frame_parms->symbol_rotation[1][2 * (s + symb_offset)], + (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], + frame_parms->ofdm_symbol_size, + 15); } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 4ac1c47b02..28b6677b2c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -213,7 +213,7 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2) } for (int n=0; n < LENGTH_PSS_NR; n++) { - int m = (n + 43*N_ID_2)%(LENGTH_PSS_NR); + int m = (n + 43*N_ID_2)%(LENGTH_PSS_NR); d_pss[n] = 1 - 2*x[m]; } diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index f6cb93ed03..b45c1abf0b 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -225,6 +225,8 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye } static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) { + if ( values == NULL ) + return; fl_winset(FL_ObjWin(graph->graph)); const int samplesPerPixel=datasize/graph->w; int displayPart=graph->waterFallh-ScaleZone; @@ -280,30 +282,6 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in graph->iteration++; } -static void genericLogPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) { - float *values, *time; - oai_xygraph_getbuff(graph, &time, &values, len, 0); - - for (int ant=0; ant #include #include @@ -3103,10 +3103,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale) dft64((int16_t*)(xtmp),(int16_t*)ytmp,1); dft64((int16_t*)(xtmp+32),(int16_t*)(ytmp+16),1); +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("dft128a.m","dfta",ytmp,64,1,1); LOG_M("dft128b.m","dftb",ytmp+16,64,1,1); } +#endif for (i=0; i<16; i++) { bfly2_16(ytmpp,ytmpp+16, y128p,y128p+16, @@ -3155,10 +3157,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale) } +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("dft128out.m","dft128",y,128,1,1); exit(-1); } +#endif _mm_empty(); _m_empty(); @@ -3183,18 +3187,20 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale) transpose4_ooff_simd256(x256+10,xtmp+5,8); transpose4_ooff_simd256(x256+12,xtmp+6,8); transpose4_ooff_simd256(x256+14,xtmp+7,8); +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("dft128ina_256.m","dftina",xtmp,64,1,1); LOG_M("dft128inb_256.m","dftinb",xtmp+8,64,1,1); } - +#endif dft64((int16_t*)(xtmp),(int16_t*)ytmp,1); dft64((int16_t*)(xtmp+8),(int16_t*)(ytmp+8),1); +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("dft128outa_256.m","dftouta",ytmp,64,1,1); LOG_M("dft128outb_256.m","dftoutb",ytmp+8,64,1,1); } - +#endif for (i=0; i<8; i++) { bfly2_16_256(ytmpp,ytmpp+8, y256p,y256p+8, @@ -3226,10 +3232,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale) y256[15] = mulhi_int16_simd256(y256[15],ONE_OVER_SQRT2_Q15_256); } +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("dft128.m","dft",y256,128,1,1); exit(-1); } +#endif } #endif @@ -5952,8 +5960,6 @@ void idft32768(int16_t *x,int16_t *y,unsigned char scale) #endif - - int16_t twa1536[1024],twb1536[1024]; // 512 x 3 @@ -6033,11 +6039,13 @@ void dft1536(int16_t *input, int16_t *output, unsigned char scale) tmpo[1][i] = tmpo[1][i<<1]; tmpo[2][i] = tmpo[2][i<<1]; }*/ +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("dft1536out0.m","o0",tmpo[0],2048,1,1); LOG_M("dft1536out1.m","o1",tmpo[1],2048,1,1); LOG_M("dft1536out2.m","o2",tmpo[2],2048,1,1); } +#endif for (i=0,i2=0; i<1024; i+=8,i2+=4) { bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+1024+i),(simd_q15_t*)(output+2048+i), @@ -6195,14 +6203,14 @@ void idft6144(int16_t *input, int16_t *output,unsigned char scale) idft2048((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1); idft2048((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1); idft2048((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1); - +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("idft6144in.m","in",input,6144,1,1); LOG_M("idft6144out0.m","o0",tmpo[0],2048,1,1); LOG_M("idft6144out1.m","o1",tmpo[1],2048,1,1); LOG_M("idft6144out2.m","o2",tmpo[2],2048,1,1); } - +#endif for (i=0,i2=0; i<4096; i+=8,i2+=4) { ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i), @@ -6262,11 +6270,13 @@ void dft6144(int16_t *input, int16_t *output,unsigned char scale) tmpo[1][i] = tmpo[1][i<<1]; tmpo[2][i] = tmpo[2][i<<1]; }*/ +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("ft6144out0.m","o0",tmpo[0],2048,1,1); LOG_M("ft6144out1.m","o1",tmpo[1],2048,1,1); LOG_M("ft6144out2.m","o2",tmpo[2],2048,1,1); } +#endif for (i=0,i2=0; i<4096; i+=8,i2+=4) { bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i), @@ -6338,11 +6348,13 @@ void dft12288(int16_t *input, int16_t *output,unsigned char scale) tmpo[1][i] = tmpo[1][i<<1]; tmpo[2][i] = tmpo[2][i<<1]; }*/ +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("dft12288out0.m","o0",tmpo[0],4096,1,1); LOG_M("dft12288out1.m","o1",tmpo[1],4096,1,1); LOG_M("dft12288out2.m","o2",tmpo[2],4096,1,1); } +#endif for (i=0,i2=0; i<8192; i+=8,i2+=4) { bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i), @@ -6394,14 +6406,14 @@ void idft12288(int16_t *input, int16_t *output,unsigned char scale) idft4096((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),scale); idft4096((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),scale); idft4096((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),scale); - +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("idft12288in.m","in",input,12288,1,1); LOG_M("idft12288out0.m","o0",tmpo[0],4096,1,1); LOG_M("idft12288out1.m","o1",tmpo[1],4096,1,1); LOG_M("idft12288out2.m","o2",tmpo[2],4096,1,1); } - +#endif for (i=0,i2=0; i<8192; i+=8,i2+=4) { ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i), @@ -6431,9 +6443,11 @@ void idft12288(int16_t *input, int16_t *output,unsigned char scale) } _mm_empty(); _m_empty(); +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("idft12288out.m","out",output,6144,1,1); } +#endif } int16_t twa18432[12288] __attribute__((aligned(32))); @@ -6562,11 +6576,13 @@ void dft24576(int16_t *input, int16_t *output,unsigned char scale) tmpo[1][i] = tmpo[1][i<<1]; tmpo[2][i] = tmpo[2][i<<1]; }*/ +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("dft24576out0.m","o0",tmpo[0],8192,1,1); LOG_M("dft24576out1.m","o1",tmpo[1],8192,1,1); LOG_M("dft24576out2.m","o2",tmpo[2],8192,1,1); } +#endif for (i=0,i2=0; i<16384; i+=8,i2+=4) { bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i), @@ -6597,9 +6613,11 @@ void dft24576(int16_t *input, int16_t *output,unsigned char scale) } _mm_empty(); _m_empty(); +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("out.m","out",output,24576,1,1); } +#endif } void idft24576(int16_t *input, int16_t *output,unsigned char scale) @@ -6619,14 +6637,14 @@ void idft24576(int16_t *input, int16_t *output,unsigned char scale) idft8192((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1); idft8192((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1); idft8192((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1); - + #ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("idft24576in.m","in",input,24576,1,1); LOG_M("idft24576out0.m","o0",tmpo[0],8192,1,1); LOG_M("idft24576out1.m","o1",tmpo[1],8192,1,1); LOG_M("idft24576out2.m","o2",tmpo[2],8192,1,1); } - +#endif for (i=0,i2=0; i<16384; i+=8,i2+=4) { ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i), @@ -6655,10 +6673,11 @@ void idft24576(int16_t *input, int16_t *output,unsigned char scale) } _mm_empty(); _m_empty(); - +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("idft24576out.m","out",output,24576,1,1); } +#endif } int16_t twa36864[24576] __attribute__((aligned(32))); @@ -6682,13 +6701,13 @@ void dft36864(int16_t *input, int16_t *output,uint8_t scale) { dft12288((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1); dft12288((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1); dft12288((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1); - +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("dft36864out0.m","o0",tmpo[0],12288,1,1); LOG_M("dft36864out1.m","o1",tmpo[1],12288,1,1); LOG_M("dft36864out2.m","o2",tmpo[2],12288,1,1); } - +#endif for (i=0,i2=0; i<24576; i+=8,i2+=4) { bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]), (simd_q15_t*)(output+i),(simd_q15_t*)(output+24576+i),(simd_q15_t*)(output+49152+i), @@ -6718,9 +6737,11 @@ void dft36864(int16_t *input, int16_t *output,uint8_t scale) { } _mm_empty(); _m_empty(); +#ifndef MR_MAIN if (LOG_DUMPFLAG(DEBUG_DFT)) { LOG_M("out.m","out",output,36864,1,1); } +#endif } void idft36864(int16_t *input, int16_t *output,uint8_t scale) { @@ -9471,6 +9492,919 @@ void dft1200(int16_t *x,int16_t *y,unsigned char scale_flag) } + +static int16_t twa1296[431*2*4]; +static int16_t twb1296[431*2*4]; + +void dft1296(int16_t *x,int16_t *y,unsigned char scale_flag) //432 * 3 +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1296[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1296[0]; + simd_q15_t x2128[1296];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1296];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<432; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+432] = x128[j+1]; + x2128[i+864] = x128[j+2]; + } + + dft432((int16_t *)x2128,(int16_t *)ytmp128,1); + dft432((int16_t *)(x2128+432),(int16_t *)(ytmp128+432),1); + dft432((int16_t *)(x2128+864),(int16_t *)(ytmp128+864),1); + + bfly3_tw1(ytmp128,ytmp128+432,ytmp128+864,y128,y128+432,y128+864); + + for (i=1,j=0; i<432; i++,j++) { + bfly3(ytmp128+i, + ytmp128+432+i, + ytmp128+864+i, + y128+i, + y128+432+i, + y128+864+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1296; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + + +static int16_t twa1440[479*2*4]; +static int16_t twb1440[479*2*4]; + +void dft1440(int16_t *x,int16_t *y,unsigned char scale_flag) // 480 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1440[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1440[0]; + simd_q15_t x2128[1440];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1440];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<480; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+480] = x128[j+1]; + x2128[i+960] = x128[j+2]; + } + + dft480((int16_t *)x2128,(int16_t *)ytmp128,1); + dft480((int16_t *)(x2128+480),(int16_t *)(ytmp128+480),1); + dft480((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1); + + bfly3_tw1(ytmp128,ytmp128+480,ytmp128+960,y128,y128+480,y128+960); + + for (i=1,j=0; i<480; i++,j++) { + bfly3(ytmp128+i, + ytmp128+480+i, + ytmp128+960+i, + y128+i, + y128+480+i, + y128+960+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1440; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1500[2392]__attribute__((aligned(32))); +static int16_t twb1500[2392]__attribute__((aligned(32))); +static int16_t twc1500[2392]__attribute__((aligned(32))); +static int16_t twd1500[2392]__attribute__((aligned(32))); + +void dft1500(int16_t *x,int16_t *y,unsigned char scale_flag) +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1500[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1500[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc1500[0]; + simd_q15_t *twd128=(simd_q15_t *)&twd1500[0]; + simd_q15_t x2128[1500];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1500];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<300; i++,j+=5) { + x2128[i] = x128[j]; + x2128[i+300] = x128[j+1]; + x2128[i+600] = x128[j+2]; + x2128[i+900] = x128[j+3]; + x2128[i+1200] = x128[j+4]; + } + + dft300((int16_t *)x2128,(int16_t *)ytmp128,1); + dft300((int16_t *)(x2128+300),(int16_t *)(ytmp128+300),1); + dft300((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft300((int16_t *)(x2128+900),(int16_t *)(ytmp128+900),1); + dft300((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + + bfly5_tw1(ytmp128,ytmp128+300,ytmp128+600,ytmp128+900,ytmp128+1200,y128,y128+300,y128+600,y128+900,y128+1200); + + for (i=1,j=0; i<300; i++,j++) { + bfly5(ytmp128+i, + ytmp128+300+i, + ytmp128+600+i, + ytmp128+900+i, + ytmp128+1200+i, + y128+i, + y128+300+i, + y128+600+i, + y128+900+i, + y128+1200+i, + twa128+j, + twb128+j, + twc128+j, + twd128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[15]); + + for (i=0; i<1500; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +} + +static int16_t twa1620[539*2*4]; +static int16_t twb1620[539*2*4]; + +void dft1620(int16_t *x,int16_t *y,unsigned char scale_flag) // 540 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1620[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1620[0]; + simd_q15_t x2128[1620];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1620];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<540; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+540] = x128[j+1]; + x2128[i+1080] = x128[j+2]; + } + + dft540((int16_t *)x2128,(int16_t *)ytmp128,1); + dft540((int16_t *)(x2128+540),(int16_t *)(ytmp128+540),1); + dft540((int16_t *)(x2128+1080),(int16_t *)(ytmp128+1080),1); + + bfly3_tw1(ytmp128,ytmp128+540,ytmp128+1080,y128,y128+540,y128+1080); + + for (i=1,j=0; i<540; i++,j++) { + bfly3(ytmp128+i, + ytmp128+540+i, + ytmp128+1080+i, + y128+i, + y128+540+i, + y128+1080+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1620; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1728[575*2*4]; +static int16_t twb1728[575*2*4]; + +void dft1728(int16_t *x,int16_t *y,unsigned char scale_flag) // 576 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1728[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1728[0]; + simd_q15_t x2128[1728];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1728];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<576; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+576] = x128[j+1]; + x2128[i+1152] = x128[j+2]; + } + + dft576((int16_t *)x2128,(int16_t *)ytmp128,1); + dft576((int16_t *)(x2128+576),(int16_t *)(ytmp128+576),1); + dft576((int16_t *)(x2128+1152),(int16_t *)(ytmp128+1152),1); + + bfly3_tw1(ytmp128,ytmp128+576,ytmp128+1152,y128,y128+576,y128+1152); + + for (i=1,j=0; i<576; i++,j++) { + bfly3(ytmp128+i, + ytmp128+576+i, + ytmp128+1152+i, + y128+i, + y128+576+i, + y128+1152+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1728; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1800[599*2*4]; +static int16_t twb1800[599*2*4]; + +void dft1800(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1800[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1800[0]; + simd_q15_t x2128[1800];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1800];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<600; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+600] = x128[j+1]; + x2128[i+1200] = x128[j+2]; + } + + dft600((int16_t *)x2128,(int16_t *)ytmp128,1); + dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + + bfly3_tw1(ytmp128,ytmp128+600,ytmp128+1200,y128,y128+600,y128+1200); + + for (i=1,j=0; i<600; i++,j++) { + bfly3(ytmp128+i, + ytmp128+600+i, + ytmp128+1200+i, + y128+i, + y128+600+i, + y128+1200+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1800; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1920[479*2*4]; +static int16_t twb1920[479*2*4]; +static int16_t twc1920[479*2*4]; + +void dft1920(int16_t *x,int16_t *y,unsigned char scale_flag) // 480 x 4 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1920[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1920[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc1920[0]; + simd_q15_t x2128[1920];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1920];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<480; i++,j+=4) { + x2128[i] = x128[j]; + x2128[i+480] = x128[j+1]; + x2128[i+960] = x128[j+2]; + x2128[i+1440] = x128[j+3]; + } + + dft480((int16_t *)x2128,(int16_t *)ytmp128,1); + dft480((int16_t *)(x2128+480),(int16_t *)(ytmp128+480),1); + dft480((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1); + dft480((int16_t *)(x2128+1440),(int16_t *)(ytmp128+1440),1); + + bfly4_tw1(ytmp128,ytmp128+480,ytmp128+960,ytmp128+1440,y128,y128+480,y128+960,y128+1440); + + for (i=1,j=0; i<480; i++,j++) { + bfly4(ytmp128+i, + ytmp128+480+i, + ytmp128+960+i, + ytmp128+1440+i, + y128+i, + y128+480+i, + y128+960+i, + y128+1440+i, + twa128+j, + twb128+j, + twc128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[13]); + for (i=0; i<1920; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa1944[647*2*4]; +static int16_t twb1944[647*2*4]; + +void dft1944(int16_t *x,int16_t *y,unsigned char scale_flag) // 648 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa1944[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb1944[0]; + simd_q15_t x2128[1944];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[1944];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<648; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+648] = x128[j+1]; + x2128[i+1296] = x128[j+2]; + } + + dft648((int16_t *)x2128,(int16_t *)ytmp128,1); + dft648((int16_t *)(x2128+648),(int16_t *)(ytmp128+648),1); + dft648((int16_t *)(x2128+1296),(int16_t *)(ytmp128+1296),1); + + bfly3_tw1(ytmp128,ytmp128+648,ytmp128+1296,y128,y128+648,y128+1296); + + for (i=1,j=0; i<648; i++,j++) { + bfly3(ytmp128+i, + ytmp128+648+i, + ytmp128+1296+i, + y128+i, + y128+648+i, + y128+1296+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<1944; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2160[719*2*4]; +static int16_t twb2160[719*2*4]; + +void dft2160(int16_t *x,int16_t *y,unsigned char scale_flag) // 720 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2160[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2160[0]; + simd_q15_t x2128[2160];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2160];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<720; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+720] = x128[j+1]; + x2128[i+1440] = x128[j+2]; + } + + dft720((int16_t *)x2128,(int16_t *)ytmp128,1); + dft720((int16_t *)(x2128+720),(int16_t *)(ytmp128+720),1); + dft720((int16_t *)(x2128+1440),(int16_t *)(ytmp128+1440),1); + + bfly3_tw1(ytmp128,ytmp128+720,ytmp128+1440,y128,y128+720,y128+1440); + + for (i=1,j=0; i<720; i++,j++) { + bfly3(ytmp128+i, + ytmp128+720+i, + ytmp128+1440+i, + y128+i, + y128+720+i, + y128+1440+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2160; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2304[767*2*4]; +static int16_t twb2304[767*2*4]; + +void dft2304(int16_t *x,int16_t *y,unsigned char scale_flag) // 768 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2304[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2304[0]; + simd_q15_t x2128[2304];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2304];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<768; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+768] = x128[j+1]; + x2128[i+1536] = x128[j+2]; + } + + dft768((int16_t *)x2128,(int16_t *)ytmp128,1); + dft768((int16_t *)(x2128+768),(int16_t *)(ytmp128+768),1); + dft768((int16_t *)(x2128+1536),(int16_t *)(ytmp128+1536),1); + + bfly3_tw1(ytmp128,ytmp128+768,ytmp128+1536,y128,y128+768,y128+1536); + + for (i=1,j=0; i<768; i++,j++) { + bfly3(ytmp128+i, + ytmp128+768+i, + ytmp128+1536+i, + y128+i, + y128+768+i, + y128+1536+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2304; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2400[599*2*4]; +static int16_t twb2400[599*2*4]; +static int16_t twc2400[599*2*4]; + +void dft2400(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 x 4 +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2400[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2400[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc2400[0]; + simd_q15_t x2128[2400];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2400];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<600; i++,j+=4) { + x2128[i] = x128[j]; + x2128[i+600] = x128[j+1]; + x2128[i+1200] = x128[j+2]; + x2128[i+1800] = x128[j+3]; + } + + dft600((int16_t *)x2128,(int16_t *)ytmp128,1); + dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + dft600((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1); + + bfly4_tw1(ytmp128,ytmp128+600,ytmp128+1200,ytmp128+1800,y128,y128+600,y128+1200,y128+1800); + + for (i=1,j=0; i<600; i++,j++) { + bfly4(ytmp128+i, + ytmp128+600+i, + ytmp128+1200+i, + ytmp128+1800+i, + y128+i, + y128+600+i, + y128+1200+i, + y128+1800+i, + twa128+j, + twb128+j, + twc128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[13]); + for (i=0; i<2400; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2592[863*2*4]; +static int16_t twb2592[863*2*4]; + +void dft2592(int16_t *x,int16_t *y,unsigned char scale_flag) // 864 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2592[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2592[0]; + simd_q15_t x2128[2592];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2592];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<864; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+864] = x128[j+1]; + x2128[i+1728] = x128[j+2]; + } + + dft864((int16_t *)x2128,(int16_t *)ytmp128,1); + dft864((int16_t *)(x2128+864),(int16_t *)(ytmp128+864),1); + dft864((int16_t *)(x2128+1728),(int16_t *)(ytmp128+1728),1); + + bfly3_tw1(ytmp128,ytmp128+864,ytmp128+1728,y128,y128+864,y128+1728); + + for (i=1,j=0; i<864; i++,j++) { + bfly3(ytmp128+i, + ytmp128+864+i, + ytmp128+1728+i, + y128+i, + y128+864+i, + y128+1728+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2592; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2700[899*2*4]; +static int16_t twb2700[899*2*4]; + +void dft2700(int16_t *x,int16_t *y,unsigned char scale_flag) // 900 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2700[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2700[0]; + simd_q15_t x2128[2700];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2700];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<900; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+900] = x128[j+1]; + x2128[i+1800] = x128[j+2]; + } + + dft900((int16_t *)x2128,(int16_t *)ytmp128,1); + dft900((int16_t *)(x2128+900),(int16_t *)(ytmp128+900),1); + dft900((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1); + + bfly3_tw1(ytmp128,ytmp128+900,ytmp128+1800,y128,y128+900,y128+1800); + + for (i=1,j=0; i<900; i++,j++) { + bfly3(ytmp128+i, + ytmp128+900+i, + ytmp128+1800+i, + y128+i, + y128+900+i, + y128+1800+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2700; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2880[959*2*4]; +static int16_t twb2880[959*2*4]; + +void dft2880(int16_t *x,int16_t *y,unsigned char scale_flag) // 960 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2880[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2880[0]; + simd_q15_t x2128[2880];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2880];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<960; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+960] = x128[j+1]; + x2128[i+1920] = x128[j+2]; + } + + dft960((int16_t *)x2128,(int16_t *)ytmp128,1); + dft960((int16_t *)(x2128+960),(int16_t *)(ytmp128+960),1); + dft960((int16_t *)(x2128+1920),(int16_t *)(ytmp128+1920),1); + + bfly3_tw1(ytmp128,ytmp128+960,ytmp128+1920,y128,y128+960,y128+1920); + + for (i=1,j=0; i<960; i++,j++) { + bfly3(ytmp128+i, + ytmp128+960+i, + ytmp128+1920+i, + y128+i, + y128+960+i, + y128+1920+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2880; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa2916[971*2*4]; +static int16_t twb2916[971*2*4]; + +void dft2916(int16_t *x,int16_t *y,unsigned char scale_flag) // 972 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa2916[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb2916[0]; + simd_q15_t x2128[2916];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[2916];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<972; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+972] = x128[j+1]; + x2128[i+1944] = x128[j+2]; + } + + dft972((int16_t *)x2128,(int16_t *)ytmp128,1); + dft972((int16_t *)(x2128+972),(int16_t *)(ytmp128+972),1); + dft972((int16_t *)(x2128+1944),(int16_t *)(ytmp128+1944),1); + + bfly3_tw1(ytmp128,ytmp128+972,ytmp128+1944,y128,y128+972,y128+1944); + + for (i=1,j=0; i<972; i++,j++) { + bfly3(ytmp128+i, + ytmp128+972+i, + ytmp128+1944+i, + y128+i, + y128+972+i, + y128+1944+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<2916; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + +static int16_t twa3000[599*8]__attribute__((aligned(32))); +static int16_t twb3000[599*8]__attribute__((aligned(32))); +static int16_t twc3000[599*8]__attribute__((aligned(32))); +static int16_t twd3000[599*8]__attribute__((aligned(32))); + +void dft3000(int16_t *x,int16_t *y,unsigned char scale_flag) // 600 * 5 +{ + + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa3000[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb3000[0]; + simd_q15_t *twc128=(simd_q15_t *)&twc3000[0]; + simd_q15_t *twd128=(simd_q15_t *)&twd3000[0]; + simd_q15_t x2128[3000];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[3000];//=&ytmp128array2[0]; + + + + for (i=0,j=0; i<600; i++,j+=5) { + x2128[i] = x128[j]; + x2128[i+600] = x128[j+1]; + x2128[i+1200] = x128[j+2]; + x2128[i+1800] = x128[j+3]; + x2128[i+2400] = x128[j+4]; + } + + dft600((int16_t *)x2128,(int16_t *)ytmp128,1); + dft600((int16_t *)(x2128+600),(int16_t *)(ytmp128+600),1); + dft600((int16_t *)(x2128+1200),(int16_t *)(ytmp128+1200),1); + dft600((int16_t *)(x2128+1800),(int16_t *)(ytmp128+1800),1); + dft600((int16_t *)(x2128+2400),(int16_t *)(ytmp128+2400),1); + + bfly5_tw1(ytmp128,ytmp128+600,ytmp128+1200,ytmp128+1800,ytmp128+2400,y128,y128+600,y128+1200,y128+1800,y128+2400); + + for (i=1,j=0; i<600; i++,j++) { + bfly5(ytmp128+i, + ytmp128+600+i, + ytmp128+1200+i, + ytmp128+1800+i, + ytmp128+2400+i, + y128+i, + y128+600+i, + y128+1200+i, + y128+1800+i, + y128+2400+i, + twa128+j, + twb128+j, + twc128+j, + twd128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[15]); + + for (i=0; i<3000; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +} + +static int16_t twa3240[1079*2*4]; +static int16_t twb3240[1079*2*4]; + +void dft3240(int16_t *x,int16_t *y,unsigned char scale_flag) // 1080 x 3 +{ + int i,j; + simd_q15_t *x128=(simd_q15_t *)x; + simd_q15_t *y128=(simd_q15_t *)y; + simd_q15_t *twa128=(simd_q15_t *)&twa3240[0]; + simd_q15_t *twb128=(simd_q15_t *)&twb3240[0]; + simd_q15_t x2128[3240];// = (simd_q15_t *)&x2128array[0]; + simd_q15_t ytmp128[3240];//=&ytmp128array3[0]; + + + + for (i=0,j=0; i<1080; i++,j+=3) { + x2128[i] = x128[j]; + x2128[i+1080] = x128[j+1]; + x2128[i+2160] = x128[j+2]; + } + + dft1080((int16_t *)x2128,(int16_t *)ytmp128,1); + dft1080((int16_t *)(x2128+1080),(int16_t *)(ytmp128+1080),1); + dft1080((int16_t *)(x2128+2160),(int16_t *)(ytmp128+2160),1); + + bfly3_tw1(ytmp128,ytmp128+1080,ytmp128+2160,y128,y128+1080,y128+2160); + + for (i=1,j=0; i<1080; i++,j++) { + bfly3(ytmp128+i, + ytmp128+1080+i, + ytmp128+2160+i, + y128+i, + y128+1080+i, + y128+2160+i, + twa128+j, + twb128+j); + } + + if (scale_flag==1) { + norm128 = set1_int16(dft_norm_table[14]); + + for (i=0; i<3240; i++) { + y128[i] = mulhi_int16(y128[i],norm128); + } + } + + _mm_empty(); + _m_empty(); + +}; + void init_rad4(int N,int16_t *tw) { int16_t *twa = tw; @@ -9492,7 +10426,7 @@ void init_rad4_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc) { int i,j; for (i=1;i<(N/4);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); @@ -9525,7 +10459,7 @@ void init_rad2_rep(int N,int16_t *twa) { int i,j; for (i=1;i<(N/2);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); for (j=1;j<4;j++) { ((int32_t*)twa)[j]=((int32_t*)twa)[0]; @@ -9551,7 +10485,7 @@ void init_rad3_rep(int N,int16_t *twa,int16_t *twb) { int i,j; for (i=1;i<(N/3);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); @@ -9569,7 +10503,7 @@ void init_rad5_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc,int16_t *twd) { int i,j; for (i=1;i<(N/5);i++) { - twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); + twa[0] = (int16_t)round(32767.0*cos(2*M_PI*i/N)); twa[1] = -(int16_t)round(32767.0*sin(2*M_PI*i/N)); twb[0] = (int16_t)round(32767.0*cos(2*M_PI*2*i/N)); twb[1] = -(int16_t)round(32767.0*sin(2*M_PI*2*i/N)); @@ -9586,7 +10520,7 @@ void init_rad5_rep(int N,int16_t *twa,int16_t *twb,int16_t *twc,int16_t *twd) { twa+=8; twb+=8; twc+=8; - twd+=8; + twd+=8; } } /*----------------------------------------------------------------*/ @@ -9600,7 +10534,7 @@ int dfts_autoinit(void) init_rad2(8192,tw8192); init_rad4(16384,tw16384); init_rad2(32768,tw32768); - + init_rad3(1536,twa1536,twb1536); init_rad3(3072,twa3072,twb3072); init_rad3(6144,twa6144,twb6144); @@ -9645,6 +10579,24 @@ int dfts_autoinit(void) init_rad3_rep(1080,twa1080,twb1080); init_rad4_rep(1152,twa1152,twb1152,twc1152); init_rad4_rep(1200,twa1200,twb1200,twc1200); + init_rad3_rep(1296,twa1296,twb1296); + init_rad3_rep(1440,twa1440,twb1440); + init_rad5_rep(1500,twa1500,twb1500,twc1500,twd1500); + init_rad3_rep(1620,twa1620,twb1620); + init_rad3_rep(1728,twa1728,twb1728); + init_rad3_rep(1800,twa1800,twb1800); + init_rad4_rep(1920,twa1920,twb1920, twc1920); + init_rad3_rep(1944,twa1944,twb1944); + init_rad3_rep(2160,twa2160,twb2160); + init_rad3_rep(2304,twa2304,twb2304); + init_rad4_rep(2400,twa2400,twb2400,twc2400); + init_rad3_rep(2592,twa2592,twb2592); + init_rad3_rep(2700,twa2700,twb2700); + init_rad3_rep(2880,twa2880,twb2880); + init_rad3_rep(2916,twa2916,twb2916); + init_rad5_rep(3000,twa3000,twb3000,twc3000,twd3000); + init_rad3_rep(3240,twa3240,twb3240); + return 0; } diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 12467e1fdc..db7ac3d813 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -226,9 +226,26 @@ void dft1024(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1080(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1152(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1200(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1296(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1440(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1500(int16_t *x,int16_t *y,uint8_t scale_flag); void dft1536(int16_t *sigF,int16_t *sig,uint8_t scale_flag); +void dft1620(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1728(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1800(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1920(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft1944(int16_t *x,int16_t *y,uint8_t scale_flag); void dft2048(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2160(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2304(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2400(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2592(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2700(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2880(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft2916(int16_t *x,int16_t *y,uint8_t scale_flag); +void dft3000(int16_t *x,int16_t *y,uint8_t scale_flag); void dft3072(int16_t *sigF,int16_t *sig,uint8_t scale_flag); +void dft3240(int16_t *x,int16_t *y,uint8_t scale_flag); void dft4096(int16_t *x,int16_t *y,uint8_t scale_flag); void dft6144(int16_t *sigF,int16_t *sig,uint8_t scale_flag); void dft8192(int16_t *x,int16_t *y,uint8_t scale_flag); @@ -283,21 +300,25 @@ typedef enum DFT_size_idx { DFT_108, DFT_120, DFT_128, DFT_144, DFT_180, DFT_192, DFT_216, DFT_240, DFT_256, DFT_288, DFT_300, DFT_324, DFT_360, DFT_384, DFT_432, DFT_480, DFT_512, DFT_540, DFT_576, DFT_600, DFT_648, DFT_720, DFT_768, DFT_864, - DFT_900, DFT_960, DFT_972, DFT_1024, DFT_1080, DFT_1152, DFT_1200, DFT_1536, - DFT_2048, DFT_3072, DFT_4096, DFT_6144, DFT_8192, DFT_9216, DFT_12288, DFT_18432, - DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304, + DFT_900, DFT_960, DFT_972, DFT_1024, DFT_1080, DFT_1152, DFT_1200, DFT_1296, + DFT_1440, DFT_1500, DFT_1536, DFT_1620, DFT_1728, DFT_1800, DFT_1920, DFT_1944, + DFT_2048, DFT_2160, DFT_2304, DFT_2400, DFT_2592, DFT_2700, DFT_2880, DFT_2916, + DFT_3000, DFT_3072, DFT_3240, DFT_4096, DFT_6144, DFT_8192, DFT_9216, DFT_12288, + DFT_18432, DFT_24576, DFT_36864, DFT_49152, DFT_73728, DFT_98304, DFT_SIZE_IDXTABLESIZE } dft_size_idx_t; #ifdef OAIDFTS_MAIN adftfunc_t dft_ftab[]={ dft12, dft24, dft36, dft48, dft60, dft72, dft96, - dft108, dft120, dft128, dft144, dft180, dft192, dft216, dft240, + dft108, dft120, dft128, dft144, dft180, dft192, dft216, dft240, dft256, dft288, dft300, dft324, dft360, dft384, dft432, dft480, dft512, dft540, dft576, dft600, dft648, dft720, dft768, dft864, - dft900, dft960, dft972, dft1024, dft1080, dft1152, dft1200, dft1536, - dft2048, dft3072, dft4096, dft6144, dft8192, dft9216, dft12288, dft18432, - dft24576, dft36864, dft49152, dft73728, dft98304 + dft900, dft960, dft972, dft1024, dft1080, dft1152, dft1200, dft1296, + dft1440, dft1500, dft1536, dft1620, dft1728, dft1800, dft1920, dft1944, + dft2048, dft2160, dft2304, dft2400, dft2592, dft2700, dft2880, dft2916, + dft3000, dft3072, dft3240, dft4096, dft6144, dft8192, dft9216, dft12288, + dft18432, dft24576, dft36864, dft49152, dft73728, dft98304 }; #endif @@ -309,9 +330,9 @@ typedef enum idft_size_idx { } idft_size_idx_t; #ifdef OAIDFTS_MAIN aidftfunc_t idft_ftab[]={ - idft128, idft256, idft512, idft1024, idft1536, idft2048, idft3072, idft4096, - idft6144, idft8192, idft9216, idft12288, idft18432, idft24576, idft36864, idft49152, - idft73728, idft98304 + idft128, idft256, idft512, idft1024, idft1536, idft2048, idft3072, idft4096, + idft6144, idft8192, idft9216, idft12288, idft18432, idft24576, idft36864, idft49152, + idft73728, idft98304 }; #endif diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index b465a51a2a..86c94421f2 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -92,17 +92,17 @@ typedef enum { typedef struct { - /// \brief Holds the transmit data in the frequency domain. + /// \brief Holds the transmit data in the frequency domain (1 frame). /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + /// - second index: ? [0..samples_per_frame[ int32_t **txdata; - /// \brief holds the transmit data after beamforming in the frequency domain. + /// \brief holds the transmit data after beamforming in the frequency domain (1 slot). /// - first index: tx antenna [0..nb_antennas_tx[ - /// - second index: sample [0..] + /// - second index: sample [0..samples_per_slot_woCP] int32_t **txdataF_BF; - /// \brief holds the transmit data before beamforming in the frequency domain. - /// - first index: tx antenna [0..nb_antennas_tx[ - /// - second index: sample [0..] + /// \brief holds the transmit data before beamforming in the frequency domain (1 frame). + /// - first index: tx antenna [0..nb_antenna_ports[ + /// - second index: sample [0..samples_per_frame_woCP] int32_t **txdataF; /// \brief holds the transmit data before beamforming for epdcch/mpdcch /// - first index : tx antenna [0..nb_epdcch_antenna_ports[ @@ -128,6 +128,10 @@ typedef struct { /// - second index: tx antenna [0..nb_antennas_tx[ /// - third index: frequency [0..] int32_t **tdd_calib_coeffs; + /// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU) + /// - first index: antenna port + /// - second index: beam_id [0.. symbols_per_frame[ + uint8_t **beam_id; } RU_COMMON; @@ -741,4 +745,10 @@ typedef struct RRU_config_s { MBSFN_config_t MBSFN_config[8]; } RRU_config_t; +typedef struct processingData_RU { + int frame_tx; + int slot_tx; + openair0_timestamp timestamp_tx; + RU_t *ru; +} processingData_RU_t; #endif //__PHY_DEFS_RU__H__ diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index b7923adb0b..2f6c4324b0 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -138,8 +138,10 @@ typedef struct { typedef struct { /// 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) + /// TX buffers for UE-spec transmission (antenna layers 1,...,4 after to precoding) int32_t *txdataF[NR_MAX_NB_LAYERS]; + /// TX buffers for UE-spec transmission (antenna ports 1000 or 1001,...,1007, before precoding) + int32_t *txdataF_precoding[NR_MAX_NB_LAYERS]; /// Modulated symbols buffer int32_t *mod_symbs[NR_MAX_NB_CODEWORDS]; /// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers? @@ -180,7 +182,10 @@ typedef struct { int16_t sqrt_rho_b; } NR_gNB_DLSCH_t; - +typedef struct { + bool active; + nfapi_nr_dl_tti_ssb_pdu ssb_pdu; +} NR_gNB_SSB_t; typedef struct { int frame; @@ -385,8 +390,12 @@ typedef struct { /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //? /// - first index: eNB id [0..2] (hard coded) /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports. - /// - third index: sample [0..] + /// - third index: sample [0..samples_per_frame_woCP] int32_t **txdataF; + /// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU) + /// - first index: antenna port + /// - second index: beam_id [0.. symbols_per_frame[ + uint8_t **beam_id; int32_t *debugBuff; int32_t debugBuff_sample_offset; } NR_gNB_COMMON; @@ -705,10 +714,10 @@ typedef struct PHY_VARS_gNB_s { // nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu; // nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu; - nfapi_nr_dl_tti_ssb_pdu ssb_pdu; uint16_t num_pdsch_rnti[80]; - NR_gNB_PBCH pbch; + NR_gNB_SSB_t ssb[64]; + NR_gNB_PBCH pbch; nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL]; NR_gNB_COMMON common_vars; NR_gNB_PRACH prach_vars; @@ -791,6 +800,7 @@ typedef struct PHY_VARS_gNB_s { int prach_energy_counter; int pucch0_thres; + uint64_t bad_pucch; /* time_stats_t phy_proc; */ @@ -830,6 +840,9 @@ typedef struct PHY_VARS_gNB_s { time_stats_t ulsch_freq_offset_estimation_stats; */ notifiedFIFO_t *respDecode; + notifiedFIFO_t *resp_L1; + notifiedFIFO_t *resp_L1_tx; + notifiedFIFO_t *resp_RU_tx; tpool_t *threadPool; int nbDecode; uint8_t pusch_proc_threads; @@ -871,4 +884,13 @@ union ldpcReqUnion { uint64_t p; }; +typedef struct processingData_L1 { + int frame_rx; + int frame_tx; + int slot_rx; + int slot_tx; + openair0_timestamp timestamp_tx; + PHY_VARS_gNB *gNB; +} processingData_L1_t; + #endif diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 390574a66b..bf0a7bc9e5 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -142,6 +142,7 @@ typedef struct { uint32_t rsrp[7]; float rsrp_filtered[7]; // after layer 3 filtering float rsrq_filtered[7]; + short rsrp_dBm[7]; // common measurements //! estimated noise power (linear) unsigned int n0_power[NB_ANTENNAS_RX]; @@ -187,7 +188,7 @@ typedef struct { //! estimated rssi (dBm) 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_gNB_MAX][2]; + int rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][4][4]; //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) int rx_correlation_dB[NUMBER_OF_CONNECTED_gNB_MAX][2]; @@ -332,12 +333,10 @@ typedef struct { int32_t **dl_ch_magb1[8][8]; /// \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[ + /// \brief Cross-correlation Matrix of the gNB Tx channel signals. + /// - first index: aatx*n_rx+aarx for all aatx=[0..n_tx[ and aarx=[0..nb_rx[ /// - second index: symbol [0..] - int32_t **rho; - /// never used... always send dl_ch_rho_ext instead... - int32_t **rho_i; + int32_t ***rho; /// \brief Pointers to llr vectors (2 TBs). /// - first index: ? [0..1] (hard coded) /// - second index: ? [0..1179743] (hard coded) @@ -842,9 +841,15 @@ typedef struct { /// PDSCH DMRS uint32_t ****nr_gold_pdsch[NUMBER_OF_CONNECTED_eNB_MAX]; + // Scrambling IDs used in PDSCH DMRS + uint16_t scramblingID[2]; + /// PDCCH DMRS uint32_t ***nr_gold_pdcch[NUMBER_OF_CONNECTED_eNB_MAX]; + // Scrambling IDs used in PDCCH DMRS + uint16_t scramblingID_pdcch; + /// PUSCH DMRS sequence uint32_t ****nr_gold_pusch_dmrs; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 18c7dd413b..398252c37b 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -327,7 +327,8 @@ struct NR_DL_FRAME_PARMS { /// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP) lte_prefix_type_t Ncp; /// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211 - int16_t symbol_rotation[224*2]; + /// First dimension is for the direction of the link (0 DL, 1 UL) + int16_t symbol_rotation[2][224*2]; /// shift of pilot position in one RB uint8_t nushift; /// SRS configuration from TS 38.331 RRC @@ -368,20 +369,4 @@ struct NR_DL_FRAME_PARMS { #define KHz (1000UL) #define MHz (1000*KHz) -typedef struct nr_bandentry_s { - int16_t band; - uint64_t ul_min; - uint64_t ul_max; - uint64_t dl_min; - uint64_t dl_max; - uint64_t step_size; - uint64_t N_OFFs_DL; - uint8_t deltaf_raster; -} nr_bandentry_t; - -typedef struct nr_band_info_s { - int nbands; - nr_bandentry_t band_info[100]; -} nr_band_info_t; - #endif diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index a8548af8dc..fa021ffe81 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -275,6 +275,12 @@ #define NR_UE_CAPABILITY_SLOT_RX_TO_TX (6) /* FFS_NR_TODO it defines ue capability which is the number of slots */ /* - between reception of pdsch and tarnsmission of its acknowlegment */ /* - between reception of un uplink grant and its related transmission */ +#ifndef NO_RAT_NR + #define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */ +#else + #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 NR_MAX_HARQ_PROCESSES (16) #define NR_MAX_ULSCH_HARQ_PROCESSES (NR_MAX_HARQ_PROCESSES) /* cf 38.214 6.1 UE procedure for receiving the physical uplink shared channel */ diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h index 4da1fa63ec..6b9121e17f 100644 --- a/openair1/SCHED/fapi_l1.h +++ b/openair1/SCHED/fapi_l1.h @@ -31,6 +31,7 @@ */ #include "PHY/defs_eNB.h" +#include "PHY/defs_gNB.h" #include "PHY/phy_extern.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" #include "SCHED/sched_eNB.h" diff --git a/openair1/SCHED/nfapi_lte_dummy.c b/openair1/SCHED/nfapi_lte_dummy.c new file mode 100644 index 0000000000..9562e2de30 --- /dev/null +++ b/openair1/SCHED/nfapi_lte_dummy.c @@ -0,0 +1,50 @@ +//Dummy NR defs to avoid linking errors + +#include "PHY/defs_gNB.h" +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" +#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" +#include "openair1/PHY/LTE_TRANSPORT/transport_common.h" + +void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB, + int frame, int slot, + nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu){} + +void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu){} + +int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type){return 0;} +void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, + uint8_t *sdu){ + } +int l1_north_init_gNB(void){return 0;} + +uint8_t slot_ahead=6; +//uint8_t nfapi_mode=0; +NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return NULL;} + +void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB, + int frame, int slot, + nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu){} +void nr_fill_ulsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pusch_pdu_t *ulsch_pdu){} +void nr_fill_pucch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pucch_pdu_t *pucch_pdu){} +void nr_fill_prach(PHY_VARS_gNB *gNB, + int SFN, + int Slot, + nfapi_nr_prach_pdu_t *prach_pdu){} +void nr_fill_prach_ru(RU_t *ru, + int SFN, + int Slot, + nfapi_nr_prach_pdu_t *prach_pdu){} + +void nr_phy_config_request(NR_PHY_Config_t *gNB){} + +void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){} + +void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){} \ No newline at end of file diff --git a/openair1/SCHED/nfapi_nr_dummy.c b/openair1/SCHED/nfapi_nr_dummy.c new file mode 100644 index 0000000000..db20017fb8 --- /dev/null +++ b/openair1/SCHED/nfapi_nr_dummy.c @@ -0,0 +1,52 @@ +//Dummy NR defs to avoid linking errors + +#include "PHY/defs_gNB.h" +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" +#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" +#include "openair1/PHY/LTE_TRANSPORT/transport_common.h" + +void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB, + int frame, int slot, + nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu){} + +void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu){} + +int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type){return 0;} +void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, + uint8_t *sdu){ + } +int l1_north_init_gNB(void){return 0;} + +uint8_t slot_ahead=6; +//uint8_t nfapi_mode=0; +NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return NULL;} + +void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB, + int frame, int slot, + nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu){} +void nr_fill_ulsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pusch_pdu_t *ulsch_pdu){} +void nr_fill_pucch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pucch_pdu_t *pucch_pdu){} +void nr_fill_prach(PHY_VARS_gNB *gNB, + int SFN, + int Slot, + nfapi_nr_prach_pdu_t *prach_pdu){} +void nr_fill_prach_ru(RU_t *ru, + int SFN, + int Slot, + nfapi_nr_prach_pdu_t *prach_pdu){} + +void nr_phy_config_request(NR_PHY_Config_t *gNB){} + +void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){} + +//void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp){} + + \ No newline at end of file diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 84490bfad4..88f3dca070 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -33,6 +33,12 @@ #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" +#include "nfapi/oai_integration/vendor_ext.h" + +extern int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req); +extern int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req); +extern int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req); +extern int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req); extern uint8_t nfapi_mode; @@ -44,8 +50,15 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot, AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n", dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag); - LOG_D(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload); - memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu)); + uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex; + + LOG_D(PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload); + if (gNB->ssb[i_ssb].active) + AssertFatal(1==0,"SSB PDU with index %d already active\n",i_ssb); + else { + gNB->ssb[i_ssb].active = true; + memcpy((void*)&gNB->ssb[i_ssb].ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu)); + } } /*void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int subframe,gNB_L1_rxtx_proc_t *proc, @@ -126,7 +139,7 @@ void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, } void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ - + PHY_VARS_gNB *gNB; // copy data from L2 interface into L1 structures module_id_t Mod_id = Sched_INFO->module_id; @@ -160,15 +173,13 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ gNB->dlsch[i][0]->harq_mask=0; } - gNB->pbch_configured=0; - for (int i=0;idl_tti_request_body.dl_tti_pdu_list[i]; LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType); switch (dl_tti_pdu->PDUType) { case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: - gNB->pbch_configured=1; + if(NFAPI_MODE != NFAPI_MODE_VNF) handle_nr_nfapi_ssb_pdu(gNB,frame,slot, dl_tti_pdu); @@ -176,7 +187,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: AssertFatal(pdcch_received == 0, "pdcch_received is not 0, we can only handle one PDCCH PDU per slot\n"); - LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot); + if(NFAPI_MODE != NFAPI_MODE_VNF) handle_nfapi_nr_pdcch_pdu(gNB, frame, slot, &dl_tti_pdu->pdcch_pdu); @@ -193,33 +204,61 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n", pduIndex,TX_req->pdu_list[pduIndex].num_TLV); uint8_t *sdu = (uint8_t *)TX_req->pdu_list[pduIndex].TLVs[0].value.direct; + if(NFAPI_MODE != NFAPI_MODE_VNF) handle_nr_nfapi_pdsch_pdu(gNB,frame,slot,&dl_tti_pdu->pdsch_pdu, sdu); } } } // if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t)); + if(NFAPI_MODE != NFAPI_MODE_VNF) + for (int i=0;iul_dci_pdu_list[i]); + } + + if(NFAPI_MODE != NFAPI_MODE_VNF) + for (int i = 0; i < number_ul_tti_pdu; i++) { + switch (UL_tti_req->pdus_list[i].pdu_type) { + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); + nr_fill_ulsch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu); + break; + case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); + nr_fill_pucch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu); + break; + case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); + nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; + nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); + if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); + break; + } + } + + if(NFAPI_MODE != NFAPI_MONOLITHIC && number_ul_tti_pdu>0) + { + oai_nfapi_ul_tti_req(UL_tti_req); + } - for (int i=0;iul_dci_pdu_list[i]); + if (NFAPI_MODE != NFAPI_MONOLITHIC && Sched_INFO->UL_dci_req->numPdus!=0) + { + oai_nfapi_ul_dci_req(Sched_INFO->UL_dci_req); + } + + if (NFAPI_MODE != NFAPI_MONOLITHIC) + { + if(Sched_INFO->DL_req->dl_tti_request_body.nPDUs>0) + { + Sched_INFO->DL_req->SFN = frame; + Sched_INFO->DL_req->Slot = slot; + oai_nfapi_dl_tti_req(Sched_INFO->DL_req); + } + if (Sched_INFO->TX_req->Number_of_PDUs > 0) + { + oai_nfapi_tx_data_req(Sched_INFO->TX_req); + } + } - for (int i = 0; i < number_ul_tti_pdu; i++) { - switch (UL_tti_req->pdus_list[i].pdu_type) { - case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: - LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); - nr_fill_ulsch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu); - break; - case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: - LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); - nr_fill_pucch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu); - break; - case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: - LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); - nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; - nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); - if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); - break; - } - } } diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h index d66d6e7b24..ed90b9870b 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.h +++ b/openair1/SCHED_NR/fapi_nr_l1.h @@ -36,6 +36,11 @@ #include "nfapi_nr_interface.h" #include "nfapi_nr_interface_scf.h" +// added +void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB, + int frame,int slot, + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu); + void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO); void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB, @@ -48,3 +53,8 @@ void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid, uint8_t crc_flag); +//added + +void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB, + int frame, int slot, + nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu); diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index a78b1f4805..1b2baf03f5 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -208,6 +208,7 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size], (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset], fp->ofdm_symbol_size*sizeof(int32_t)); + } }//num_gNB == 1 @@ -279,13 +280,12 @@ static void *nr_feptx_thread(void *param) { RU_feptx_t *feptx = (RU_feptx_t *)param; RU_t *ru; - int aa, slot, start, l, nb_antenna_ports, ret; + int aa, slot, start, l, ret; int i; int32_t ***bw; NR_DL_FRAME_PARMS *fp; int ofdm_mask_full; int txdataF_offset; - int32_t *txdataF; while (!oai_exit) { ret = 0; if (wait_on_condition(&feptx->mutex_feptx,&feptx->cond_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; @@ -299,31 +299,39 @@ static void *nr_feptx_thread(void *param) { l = feptx->symbol; fp = ru->nr_frame_parms; start = feptx->symbol; - nb_antenna_ports = feptx->nb_antenna_ports; ofdm_mask_full = (1<<(ru->nb_tx*2))-1; if(ru->num_gNB != 0){ txdataF_offset = ((slot%2)*fp->samples_per_slot_wCP); ////////////precoding//////////// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1); + start_meas(&ru->precoding_stats); + + for(i=0; inb_log_antennas; ++i) { + memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot+l], + (void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot+l], + (fp->symbols_per_slot>>1)*sizeof(uint8_t)); + } + + if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) { - memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], - (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size], - (fp->samples_per_slot_wCP>>1)*sizeof(int32_t)); + memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], + (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size], + (fp->samples_per_slot_wCP>>1)*sizeof(int32_t)); } else { bw = ru->beam_weights[0]; - txdataF = &ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset]; for(i=0; isymbols_per_slot>>1; ++i){ - nr_beam_precoding(&txdataF, + nr_beam_precoding(ru->gNB_list[0]->common_vars.txdataF, ru->common.txdataF_BF, fp, bw, slot, l+i, aa, - nb_antenna_ports); + ru->nb_log_antennas, + txdataF_offset);//here } } stop_meas(&ru->precoding_stats); @@ -362,7 +370,8 @@ static void *nr_feptx_thread(void *param) { slot, l, aa, - nb_antenna_ports); + ru->nb_log_antennas, + 0); } stop_meas(&ru->precoding_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0); @@ -459,10 +468,14 @@ void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) { if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT) return; - for(i=0; inb_log_antennas; ++i) + for(i=0; inb_log_antennas; ++i) { memcpy((void*)ru->common.txdataF[i], (void*)&gNB->common_vars.txdataF[i][txdataF_offset], fp->samples_per_slot_wCP*sizeof(int32_t)); + memcpy((void*)&ru->common.beam_id[i][slot_tx*fp->symbols_per_slot], + (void*)&gNB->common_vars.beam_id[i][slot_tx*fp->symbols_per_slot], + fp->symbols_per_slot*sizeof(uint8_t)); + } if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) { @@ -485,7 +498,8 @@ void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) { tti_tx, l, aa, - ru->nb_log_antennas); + ru->nb_log_antennas, + 0); }// for (aa=0;aanb_tx;aa++) }// for (l=0;lsymbols_per_slot;l++) }// if (ru->nb_tx == 1) @@ -520,8 +534,7 @@ void nr_fep0(RU_t *ru, int first_half) { ru->common.rxdataF[aa], l, proc->tti_rx, - ru->N_TA_offset, - 0); + ru->N_TA_offset); } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 0); @@ -657,8 +670,7 @@ void nr_fep_full(RU_t *ru, int slot) { ru->common.rxdataF[aa], l, proc->tti_rx, - ru->N_TA_offset, - 0); + ru->N_TA_offset); } } diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c index 3864b2fcb2..9be6780597 100644 --- a/openair1/SCHED_NR/phy_frame_config_nr.c +++ b/openair1/SCHED_NR/phy_frame_config_nr.c @@ -41,7 +41,7 @@ * * OUTPUT: table of uplink symbol for each slot for 2 frames * -* RETURN : 0 if tdd has been properly configurated +* RETURN : nb_periods_per_frame if tdd has been properly configurated * -1 tdd configuration can not be done * * DESCRIPTION : generate bit map for uplink symbol for each slot for several frames @@ -179,7 +179,7 @@ int set_tdd_config_nr( nfapi_nr_config_request_scf_t *cfg, LOG_E(PHY,"set_tdd_configuration_nr: additionnal tdd configuration 2 is not supported for tdd configuration \n"); return (-1); }*/ - return (0); + return (nb_periods_per_frame); } /******************************************************************* diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index dea405dc90..d44c8641a6 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -67,74 +67,63 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco); } -void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { +void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) { NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; int **txdataF = gNB->common_vars.txdataF; uint8_t ssb_index, n_hf; - uint16_t ssb_start_symbol, rel_slot; + uint16_t ssb_start_symbol; int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP; uint16_t slots_per_hf = (fp->slots_per_frame)>>1; - n_hf = fp->half_frame_bit; + if (slotssb_table.ssb_period.value == 0) { - if (slotsymbols_per_slot; // start symbol wrt slot + + nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier + + LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol); + nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); + nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); + + if (cfg->carrier_config.num_tx_ant.value <= 4) + nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&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] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff; + bch[1] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff; + bch[2] = (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)); } - // to set a effective slot number in the half frame where the SSB is supposed to be - rel_slot = (n_hf)? (slot-slots_per_hf) : slot; - - LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot); - - if(rel_slot<38 && rel_slot>=0) { // there is no SSB beyond slot 37 - - for (int i=0; i<2; i++) { // max two SSB per frame - - ssb_index = i + SSB_Table[rel_slot]; // computing the ssb_index - - if ((ssb_index<64) && ((fp->L_ssb >> (63-ssb_index)) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1 - fp->ssb_index = ssb_index; - int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp); // computing the starting symbol for current ssb - ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot - - nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier - - LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol); - nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); - nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); - - if (cfg->carrier_config.num_tx_ant.value <= 4) - nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&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, - &txdataF[0][txdataF_offset], - AMP, - ssb_start_symbol, - n_hf, frame, cfg, fp); - - } - } + // Beam_id is currently used only for FR2 + if (fp->freq_range==nr_FR2){ + LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value); + for (int j=0;jsymbols_per_slot;j++) + gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value; } + + nr_generate_pbch(&gNB->pbch, + &ssb_pdu, + gNB->nr_pbch_interleaver, + &txdataF[0][txdataF_offset], + AMP, + ssb_start_symbol, + n_hf, frame, cfg, fp); } + void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame,int slot, int do_meas) { @@ -142,11 +131,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; int offset = gNB->CC_id; - uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP; - - if (cfg->ssb_table.ssb_period.value > 1) - ssb_frame_periodicity = 1 <<(cfg->ssb_table.ssb_period.value -1) ; if ((cfg->cell_config.frame_duplex_type.value == TDD) && (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return; @@ -155,15 +140,20 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, if (do_meas==1) start_meas(&gNB->phy_proc_tx); - // clear the transmit data array for the current subframe + // clear the transmit data array and beam index for the current slot for (aa=0; aacarrier_config.num_tx_ant.value; aa++) { memset(&gNB->common_vars.txdataF[aa][txdataF_offset],0,fp->samples_per_slot_wCP*sizeof(int32_t)); + memset(&gNB->common_vars.beam_id[aa][slot*fp->symbols_per_slot],255,fp->symbols_per_slot*sizeof(uint8_t)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1); - if (nfapi_mode == 0 || nfapi_mode == 1) { - if ((!(frame%ssb_frame_periodicity))) // generate SSB only for given frames according to SSB periodicity - nr_common_signal_procedures(gNB,frame, slot); + if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) { + for (int i=0; iLmax; i++) { + if (gNB->ssb[i].active) { + nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu); + gNB->ssb[i].active = false; + } + } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0); @@ -207,7 +197,9 @@ 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); + for (aa=0; aacarrier_config.num_tx_ant.value; aa++) { + apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[aa][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); } @@ -367,7 +359,6 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, int timing_advance_update, cqi; int sync_pos; - uint16_t mu = gNB->frame_parms.numerology_index; NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id][0]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; @@ -375,18 +366,10 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, // pdu->data = gNB->ulsch[ULSCH_id+1][0]->harq_processes[harq_pid]->b; sync_pos = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC - timing_advance_update = sync_pos * (1 << mu); // scale by the used scs numerology // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size - switch (gNB->frame_parms.N_RB_DL) { - case 106: timing_advance_update /= 16; break; - case 217: timing_advance_update /= 32; break; - case 245: timing_advance_update /= 32; break; - case 273: timing_advance_update /= 32; break; - case 66: timing_advance_update /= 12; break; - 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); - } + uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048; + timing_advance_update = sync_pos / bw_scaling; // put timing advance command in 0..63 range timing_advance_update += 31; @@ -463,7 +446,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { (pucch->frame == frame_rx) && (pucch->slot == slot_rx) ) { gNB->ulmask_symb = symbol; - nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch[i].pucch_pdu; + nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu; if ((symbol>=pucch_pdu->start_symbol_index) && (symbol<(pucch_pdu->start_symbol_index + pucch_pdu->nr_of_symbols))){ for (rb=0; rbprb_size; rb++) { @@ -517,15 +500,12 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) unsigned char aa; 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++) { nr_slot_fep_ul(&gNB->frame_parms, gNB->common_vars.rxdata[aa], gNB->common_vars.rxdataF[aa], symbol, slot_rx, - 0, 0); } } @@ -542,6 +522,9 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { + /* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */ + int pucch_decode_done = 0; + int pusch_decode_done = 0; 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); @@ -551,6 +534,11 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) gNB_I0_measurements(gNB); + // measure enegry in SS=10 L=4, nb_rb = 18, first_rb = 0 (corresponds to msg3) + int offset = 10*gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset; + int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12*18); + LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF); + for (int i=0;ipucch[i]; if (pucch) { @@ -558,6 +546,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) (pucch->frame == frame_rx) && (pucch->slot == slot_rx) ) { + pucch_decode_done = 1; + nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu; uint16_t num_ucis; switch (pucch_pdu->format_type) { @@ -646,6 +636,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } #endif + pusch_decode_done = 1; + uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index; uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1); @@ -671,7 +663,14 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } } // figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS - if ((frame_rx&127) == 0 && slot_rx==19) dump_pusch_stats(gNB); + if ((frame_rx&127) == 0 && slot_rx==19) { + dump_pusch_stats(gNB); + LOG_I(PHY, "Number of bad PUCCH received: %lu\n", gNB->bad_pucch); + } + + if (pucch_decode_done || pusch_decode_done) { + T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4)); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0); } diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 24885f1bb4..e0cf20d862 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -40,7 +40,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot); -void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot); +void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu); void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa); diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c index f3e5f91285..85f6d90bbe 100644 --- a/openair1/SCHED_NR_UE/harq_nr.c +++ b/openair1/SCHED_NR_UE/harq_nr.c @@ -295,7 +295,7 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u /* 38.321 5.4.2.1 2> if the uplink grant was received on PDCCH for the C-RNTI and the HARQ buffer of the identified process is empty */ if ((ulsch->harq_processes[harq_pid]->first_tx == 1) && (rnti_type == _C_RNTI_)) { /* no transmission yet on this process so consider its harq buffer as empty */ - ulsch->harq_processes[harq_pid]->first_tx = 0; + ulsch->harq_processes[harq_pid]->first_tx = 0; ulsch->harq_processes[harq_pid]->pusch_pdu.pusch_data.new_data_indicator = ndi; /* store first value of ndi */ ulsch->harq_processes[harq_pid]->round = 0; ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f516ad8639..df66217e49 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -132,6 +132,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, } switch (pdu_type){ + case FAPI_NR_RX_PDU_TYPE_SIB: case FAPI_NR_RX_PDU_TYPE_DLSCH: case FAPI_NR_RX_PDU_TYPE_RAR: harq_pid = dlsch0->current_harq_pid; @@ -202,20 +203,15 @@ uint8_t get_ra_PreambleIndex(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id){ } - -// 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; - switch (nb_rb) { - 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(); - } - return bw_scaling; +// convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with samples per second +// 16 * 64 * T_c / (2^mu) * samples_per_second +// = 16 * T_s / (2^mu) * samples_per_second +// = 16 * 1 / (15 kHz * 2048) / (2^mu) * (15 kHz * 2^mu * ofdm_symbol_size) +// = 16 * 1 / 2048 * ofdm_symbol_size +// = 16 * ofdm_symbol_size / 2048 +static inline +uint16_t get_bw_scaling(uint16_t ofdm_symbol_size){ + return 16 * ofdm_symbol_size / 2048; } // UL time alignment procedures: @@ -233,38 +229,18 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int 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; - int factor_mu = 1 << numerology; - uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB); + uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; + uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size); - 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]); + ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling; - if (ue->UE_mode[gNB_id] == RA_RESPONSE){ - - 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); - - } + LOG_I(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; @@ -800,7 +776,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ for (m = s0; m < (s0 +s1); m++) { if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) > 0) { - for (uint8_t aatx=0; aatx<1; aatx++) {//for MIMO Config: it shall loop over no_layers + for (uint8_t aatx=0; aatxharq_processes[harq_pid]->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers nr_pdsch_channel_estimation(ue, proc, 0 /*eNB_id*/, @@ -855,43 +831,24 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ slot = 1; 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) { + // process DLSCH received symbols in the slot + // symbol by symbol processing (if data/DMRS are multiplexed is checked inside the function) + if (pdsch == PDSCH || pdsch == SI_PDSCH || pdsch == RA_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 { // 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[proc->thread_id][eNB_id]->llr_offset[m]); + 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 UE_TIMING_TRACE stop_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]); #if DISABLE_LOG_X @@ -901,10 +858,9 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ #endif #endif - if(first_symbol_flag) - { - proc->first_symbol_available = 1; - } + if(first_symbol_flag) { + proc->first_symbol_available = 1; + } } // CRNTI active } return 0; @@ -925,35 +881,21 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, int harq_pid = dlsch0->current_harq_pid; int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; - int ret=0, ret1=0; + uint32_t ret = UINT32_MAX, ret1 = UINT32_MAX; 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 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; - uint16_t slots_per_subframe = ue->frame_parms.slots_per_subframe; - uint8_t numerology = ue->frame_parms.numerology_index, mapping_type_ul, mapping_type_dl; - int ul_tx_timing_adjustment, N_TA_max, factor_mu, N_t_1, N_t_2, N_1, N_2, d_1_1 = 0, d_2_1, d; - uint8_t d_2_2 = 0;// set to 0 because there is only 1 BWP - // TODO this should corresponds to the switching time as defined in - // TS 38.133 - 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 start_symbol; - float tc_factor; - 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; - dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType; + uint8_t is_cw0_active = dlsch0->harq_processes[harq_pid]->status; + uint16_t nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols; + uint16_t start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol; + uint8_t dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType; + + uint8_t nb_re_dmrs; if (dmrs_type==NFAPI_NR_DMRS_TYPE1) { nb_re_dmrs = 6*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups; } @@ -961,6 +903,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, nb_re_dmrs = 4*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups; } + uint8_t is_cw1_active = 0; if(dlsch1) is_cw1_active = dlsch1->harq_processes[harq_pid]->status; @@ -1208,7 +1151,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, 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; + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id); + nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, eNB_id, ue, dlsch0, number_pdus); break; default: break; @@ -1222,53 +1166,29 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, } } - // TODO CRC check for CW0 - - // Check CRC for CW 0 - /*if (ret == (1+dlsch0->max_turbo_iterations)) { - *dlsch_errors=*dlsch_errors+1; - 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,nr_slot_rx, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->round, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->TBS); - } - } else { - 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,nr_slot_rx, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->round, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->TBS); - } - if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){ - int j; - LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid); - - for (j=0; jharq_processes[dlsch0->current_harq_pid]->TBS>>3; j++) - LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]); - LOG_T(PHY,"\n"); - }*/ - if (ue->mac_enabled == 1) { - uint16_t bw_scaling = get_bw_scaling(ue->frame_parms.N_RB_DL); - /* Time Alignment procedure // - UE processing capability 1 // - Setting the TA update to be applied after the reception of the TA command // - Timing adjustment computed according to TS 38.213 section 4.2 // - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are // computed according to sections 5.3 and 6.4 of TS 38.214 */ - factor_mu = 1 << numerology; - N_TA_max = 3846 * bw_scaling / factor_mu; + const int numerology = ue->frame_parms.numerology_index; + const int ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; + const int nb_prefix_samples = ue->frame_parms.nb_prefix_samples; + const int samples_per_subframe = ue->frame_parms.samples_per_subframe; + const int slots_per_frame = ue->frame_parms.slots_per_frame; + const int slots_per_subframe = ue->frame_parms.slots_per_subframe; + + const double tc_factor = 1.0 / samples_per_subframe; + const uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size); + + const int Ta_max = 3846; // Max value of 12 bits TA Command + const double N_TA_max = Ta_max * bw_scaling * tc_factor; /* PDSCH decoding time N_1 for processing capability 1 */ + int N_1; if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0) N_1 = pdsch_N_1_capability_1[numerology][1]; else if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos1 || ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == 2) // TODO set to pdsch_dmrs_pos2 when available @@ -1277,12 +1197,12 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, N_1 = pdsch_N_1_capability_1[numerology][3]; /* PUSCH preapration time N_2 for processing capability 1 */ - N_2 = pusch_N_2_timing_capability_1[numerology][1]; - mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType; - mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; + const int N_2 = pusch_N_2_timing_capability_1[numerology][1]; /* d_1_1 depending on the number of PDSCH symbols allocated */ - d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH + const int d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH + int d_1_1 = 0; + mappingType_t mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType; if (mapping_type_dl == typeA) if (nb_symb_sch + start_symbol < 7) d_1_1 = 7 - (nb_symb_sch + start_symbol); @@ -1297,22 +1217,26 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, } /* d_2_1 */ + int d_2_1; + mappingType_t mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; if (mapping_type_ul == typeB && start_symbol != 0) d_2_1 = 0; else d_2_1 = 1; + /* d_2_2 */ + const double d_2_2 = 0.0; // set to 0 because there is only 1 BWP: TODO this should corresponds to the switching time as defined in TS 38.133 + /* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time // N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */ - N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu; - N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu; + double N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor; + double N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor; if (N_t_2 < d_2_2) N_t_2 = d_2_2; /* Time alignment procedure */ - // N_t_1 + N_t_2 + N_TA_max is in unit of Ts, therefore must be converted to Tc // N_t_1 + N_t_2 + N_TA_max must be in msec - tc_factor = 64 * 0.509 * 10e-7; - ul_tx_timing_adjustment = 1 + ceil(slots_per_subframe*((N_t_1 + N_t_2 + N_TA_max)*tc_factor + 0.5)/t_subframe); + const double t_subframe = 1.0; // subframe duration of 1 msec + const int ul_tx_timing_adjustment = 1 + (int)ceil(slots_per_subframe*(N_t_1 + N_t_2 + N_TA_max + 0.5)/t_subframe); if (ul_time_alignment->apply_ta == 1){ ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame; @@ -1326,13 +1250,6 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, 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); } } - - /*ue->total_TBS[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; - ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; - }*/ - - // TODO CRC check for CW1 - } } @@ -1730,15 +1647,14 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, // looking for pbch only in slot where it is supposed to be if (slot_ssb) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_IN); 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, proc, (ue->symbol_offset+i)%(fp->symbols_per_slot), - nr_slot_rx, - 0, - 0); + nr_slot_rx); #if UE_TIMING_TRACE start_meas(&ue->dlsch_channel_estimation_stats); @@ -1769,6 +1685,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); nr_ue_rrc_measurements(ue, proc, nr_slot_rx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_OUT); } } @@ -1779,21 +1696,18 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, } #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_slot_rx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_IN); 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_slot_rx, - 0, - 0); + nr_slot_rx); dci_cnt = 0; for(int n_ss = 0; n_ssnb_search_space; n_ss++) { @@ -1811,7 +1725,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, 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 @@ -1819,6 +1732,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc); } } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT); if (dci_cnt > 0) { @@ -1834,28 +1748,22 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, } if (dlsch) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_IN); uint8_t harq_pid = dlsch->current_harq_pid; NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid]; uint16_t nb_symb_sch = dlsch0_harq->nb_symbols; uint16_t start_symb_sch = dlsch0_harq->start_symbol; - int symb_dmrs = -1; 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 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, proc, m, //to be updated from higher layer - nr_slot_rx, - 0, - 0); + nr_slot_rx); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT); } } else { LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_slot_rx); @@ -1869,7 +1777,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, // do procedures for C-RNTI int ret_pdsch = 0; 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); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_IN); ret_pdsch = nr_ue_pdsch_procedures(ue, proc, gNB_id, @@ -1878,6 +1786,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, NULL); nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_OUT); } // do procedures for SI-RNTI @@ -1926,7 +1835,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, // 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); } @@ -2164,10 +2072,10 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t 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))); + int16_t ra_preamble_rx_power = (int16_t)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30); ue->tx_power_dBm[nr_slot_tx] = min(nr_get_Pcmax(mod_id), ra_preamble_rx_power); - 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", + LOG_I(PHY,"DEBUG [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d dB, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n", mod_id, frame_tx, nr_slot_tx, diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 061866b12c..00983553d8 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -56,7 +56,7 @@ UE_nr_rxtx_proc_t proc; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -uint8_t nfapi_mode = 0; +//uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3}; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 9581038283..0a7ae96e09 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -79,9 +79,9 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -int sf_ahead=4 ; -int sl_ahead=0; -uint8_t nfapi_mode = 0; +uint16_t sf_ahead=4 ; +uint16_t sl_ahead=0; +//uint8_t nfapi_mode = 0; uint64_t downlink_frequency[MAX_NUM_CCs][4]; // dummy functions @@ -97,6 +97,21 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, return 0; } +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) +{ + return; +} + +int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, + const int CC_id, + const uint8_t gNB_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *buffer_pP) +{ + return 0; +} + void rrc_data_ind( const protocol_ctxt_t *const ctxt_pP, @@ -151,8 +166,16 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( return 0; } +int nr_derive_key(int alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out) +{ + return 0; +} + void config_common(int Mod_idP, - int pdsch_AntennaPorts, + int ssb_SubcarrierOffset, + int pdsch_AntennaPorts, + int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc ); @@ -172,14 +195,18 @@ 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; -} +//nFAPI P7 dummy functions + +int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); } +int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); } +int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); } +int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ 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); +extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration /* 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 */ @@ -235,7 +262,10 @@ int main(int argc, char **argv) int i,aa;//,l; double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0; uint8_t snr1set=0; - float roundStats[50]; + double roundStats[500] = {0}; + double blerStats[500] = {0}; + double berStats[500] = {0}; + double snrStats[500] = {0}; float effRate; //float psnr; float eff_tp_check = 0.7; @@ -269,7 +299,7 @@ int main(int argc, char **argv) //uint8_t frame_mod4,num_pdcch_symbols = 0; - SCM_t channel_model=AWGN;//Rayleigh1_anticorr; + SCM_t channel_model = AWGN; // AWGN Rayleigh1 Rayleigh1_anticorr; NB_UE_INST = 1; //double pbch_sinr; @@ -428,7 +458,7 @@ int main(int argc, char **argv) case 'y': n_tx=atoi(optarg); - if ((n_tx==0) || (n_tx>2)) { + if ((n_tx==0) || (n_tx>4)) {//extend gNB to support n_tx = 4 printf("Unsupported number of tx antennas %d\n",n_tx); exit(-1); } @@ -438,7 +468,7 @@ int main(int argc, char **argv) case 'z': n_rx=atoi(optarg); - if ((n_rx==0) || (n_rx>2)) { + if ((n_rx==0) || (n_rx>4)) {//extend UE to support n_tx = 4 printf("Unsupported number of rx antennas %d\n",n_rx); exit(-1); } @@ -573,7 +603,8 @@ int main(int argc, char **argv) InitSinLUT(); get_softmodem_params()->phy_test = 1; - + get_softmodem_params()->do_ra = 0; + if (snr1set==0) snr1 = snr0+10; init_dlsch_tpool(dlsch_threads); @@ -646,20 +677,26 @@ int main(int argc, char **argv) rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon)); NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon; + NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t)); NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup)); prepare_scc(rrc.carrier.servingcellconfigcommon); - uint64_t ssb_bitmap; + uint64_t ssb_bitmap = 1; fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu); - + ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0 fix_scc(scc,ssb_bitmap); - fill_default_secondaryCellGroup(scc, - secondaryCellGroup, - 0, - 1, - n_tx, - 0); + prepare_scd(scd); + fill_default_secondaryCellGroup(scc, + scd, + secondaryCellGroup, + 0, + 1, + n_tx, + 0); + + /* RRC parameter validation for secondaryCellGroup */ + fix_scd(scd); /* -U option modify DMRS */ if(modify_dmrs) { update_dmrs_config(secondaryCellGroup, NULL,dmrs_arg); @@ -675,9 +712,9 @@ int main(int argc, char **argv) AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration - rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); + rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0,0,n_tx,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; @@ -725,7 +762,7 @@ int main(int argc, char **argv) gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, - fs, + fs/1e6,//sampling frequency in MHz bw, 30e-9, 0, @@ -740,28 +777,28 @@ int main(int argc, char **argv) frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; - s_re = malloc(2*sizeof(double*)); - s_im = malloc(2*sizeof(double*)); - r_re = malloc(2*sizeof(double*)); - r_im = malloc(2*sizeof(double*)); - txdata = malloc(2*sizeof(int*)); - - for (i=0; i<2; i++) { + s_re = malloc(n_tx*sizeof(double*)); + s_im = malloc(n_tx*sizeof(double*)); + r_re = malloc(n_rx*sizeof(double*)); + r_im = malloc(n_rx*sizeof(double*)); + txdata = malloc(n_tx*sizeof(int*)); + for (i=0; iframe_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); + UE->frame_parms.nb_antennas_rx = n_rx; if (run_initial_sync==1) UE->is_synchronized = 0; else {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;} @@ -794,7 +832,7 @@ int main(int argc, char **argv) init_nr_ue_transport(UE,0); nr_gold_pbch(UE); - nr_gold_pdcch(UE,0,2); + nr_gold_pdcch(UE,0); nr_l2_init_ue(NULL); UE_mac = get_mac_inst(0); @@ -821,7 +859,8 @@ int main(int argc, char **argv) // generate signal AssertFatal(input_fd==NULL,"Not ready for input signal file\n"); gNB->pbch_configured = 1; - gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234; + gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234; + gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0; //Configure UE rrc.carrier.MIB = (uint8_t*) malloc(4); @@ -845,7 +884,7 @@ 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.thread_id = 0; nr_ue_phy_config_request(&UE_mac->phy_config); //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels; @@ -947,16 +986,16 @@ int main(int argc, char **argv) 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); + nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[0].ssb_pdu); else phy_procedures_gNB_TX(gNB,frame,slot,0); int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP; if (n_trials==1) { - LOG_M("txsigF0.m","txsF0", &gNB->common_vars.txdataF[0][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1); + LOG_M("txsigF0.m","txsF0=", &gNB->common_vars.txdataF[0][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsigF1.m","txsF1", &gNB->common_vars.txdataF[1][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1); + LOG_M("txsigF1.m","txsF1=", &gNB->common_vars.txdataF[1][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); } 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); @@ -980,45 +1019,79 @@ int main(int argc, char **argv) } if (n_trials==1) { - LOG_M("txsig0.m","txs0", &txdata[0][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1); - if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsig1.m","txs1", &txdata[1][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1); + char filename[100];//LOG_M + for (aa=0;aaofdm_symbol_size+frame_parms->nb_prefix_samples0],6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples),1,1); + } } if (output_fd) { printf("writing txdata to binary file\n"); fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd); } - int txlev = signal_energy(&txdata[0][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); - - // if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev)); + int txlev[n_tx]; + int txlev_sum = 0; + int l_ofdm = 6; + for (aa=0; aaofdm_symbol_size + (l_ofdm-1)*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); + txlev_sum += txlev[aa]; + if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,txlev[aa],10*log10((double)txlev[aa]),txlev_sum); + } for (i=(frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)); i<(frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0)); i++) { for (aa=0; aanb_antennas_tx; aa++) { - r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); - r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); + s_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); + s_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; + //Compute AWGN variance + sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR; sigma2 = pow(10, sigma2_dB/10); - if (n_trials==1) printf("sigma2 %f (%f dB), txlev %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize)); + if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize)); + + for (aa=0; aaget_samples_slot_timestamp(slot,frame_parms,0); iget_samples_slot_timestamp(slot+1,frame_parms,0); i++) { - for (aa=0; aanb_antennas_rx; aa++) { - ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + for (int aa_rx=0; aa_rxcommon_vars.rxdata[aa_rx])[2*i] = (short) ((r_re[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) UE->common_vars.rxdata[aa_rx])[2*i+1] = (short) ((r_im[aa_rx][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]); + phase_noise(ts, &((short*) UE->common_vars.rxdata[aa_rx])[2*i], + &((short*) UE->common_vars.rxdata[aa_rx])[2*i+1]); } } } @@ -1058,10 +1131,10 @@ int main(int argc, char **argv) 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_process.f[i] == 0) && (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) { @@ -1070,7 +1143,7 @@ int main(int argc, char **argv) } errors_scrambling++; } - + } for (i = 0; i < TBS; i++) { @@ -1101,7 +1174,9 @@ int main(int argc, char **argv) if (UE_harq_process->harq_ack.ack==1) effRate += ((float)TBS)/round; } // noise trials + blerStats[snrRun] = (float) n_errors / (float) n_trials; roundStats[snrRun]/=((float)n_trials); + berStats[snrRun] = (double)errors_scrambling/available_bits/n_trials; effRate /= n_trials; printf("*****************************************\n"); printf("SNR %f, (false positive %f)\n", SNR, @@ -1109,7 +1184,7 @@ 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 %u 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, BLER %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],berStats[snrRun],blerStats[snrRun],effRate,effRate/TBS*100,TBS); printf("\n"); if (print_perf==1) { @@ -1174,15 +1249,19 @@ int main(int argc, char **argv) break; } - //if ((float)n_errors/(float)n_trials <= target_error_rate) { if (effRate > (eff_tp_check*TBS)) { printf("PDSCH test OK\n"); break; } + snrStats[snrRun] = SNR; snrRun++; } // NSR + LOG_M("dlsimStats.m","SNR",snrStats,snrRun,1,7); + LOG_MM("dlsimStats.m","BLER",blerStats,snrRun,1,7); + LOG_MM("dlsimStats.m","BER",berStats,snrRun,1,7); + LOG_MM("dlsimStats.m","rounds",roundStats,snrRun,1,7); /*if (n_trials>1) { printf("HARQ stats:\nSNR\tRounds\n"); psnr = snr0; @@ -1192,12 +1271,16 @@ int main(int argc, char **argv) } }*/ - for (i = 0; i < 2; i++) { + free_channel_desc_scm(gNB2UE); + + for (i = 0; i < n_tx; i++) { free(s_re[i]); free(s_im[i]); + free(txdata[i]); + } + for (i = 0; i < n_rx; i++) { free(r_re[i]); free(r_im[i]); - free(txdata[i]); } free(s_re); diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index 2673ca0524..32b6b10412 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -2,9 +2,16 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { re int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } //int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } -//int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); } +int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); } +int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); } +int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); } +int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); } int32_t get_uldl_offset(int nr_bandP) { return(0); } NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);} +nfapi_mode_t nfapi_mod; +nfapi_mode_t nfapi_getmode(void) { + return nfapi_mod; +} 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, diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c index 57b540f699..a930c96a75 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c @@ -2,7 +2,10 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { re int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } -//int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); } +int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); } + int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); } + int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); } + int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); } int32_t get_uldl_offset(int nr_bandP) { return(0); } NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);} int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); } diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h index a7150fb2f9..8d4acd1af1 100644 --- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h +++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h @@ -55,19 +55,6 @@ signed char quantize(double D, double x, unsigned char B) { return ((char) qxd); } - -int8_t -mac_rrc_data_req_ue( - const module_id_t Mod_idP, - const int CC_id, - const frame_t frameP, - const rb_id_t Srb_id, - const uint8_t Nb_tb, - uint8_t *const buffer_pP, - const mac_enb_index_t eNB_indexP, - const uint8_t mbsfn_sync_area - ) { return(0);} - int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);} //NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } @@ -162,13 +149,13 @@ void fill_scc(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present=NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139; scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139=0; scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig=NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet; - *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2=2; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2=6; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength=55; - *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2=2; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2=6; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength=69; - *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->k2=2; + *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->k2=6; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->mappingType=NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->startSymbolAndLength=55; *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->k2=33; @@ -235,10 +222,12 @@ 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); +void prepare_scd(NR_ServingCellConfig_t *scd); 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;} - +void configure_nr_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_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { return;} #endif diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 2ff89364d3..ee74909a9e 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -56,7 +56,7 @@ RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -uint8_t nfapi_mode = 0; +//uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; // needed for some functions @@ -101,8 +101,8 @@ void nr_phy_config_request_sim_pbchsim(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->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); + fp->ul_CarrierFreq = 3600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); if (mu>2) fp->nr_band = 257; else fp->nr_band = 78; fp->threequarter_fs= 0; @@ -111,7 +111,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, nr_init_frame_parms(gNB_config, fp); - init_symbol_rotation(fp,fp->dl_CarrierFreq); + init_symbol_rotation(fp); gNB->configured = 1; LOG_I(PHY,"gNB configured\n"); @@ -119,7 +119,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, int main(int argc, char **argv) { char c; - int i,aa;//,l; + int i,aa,start_symbol; double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; double cfo=0; uint8_t snr1set=0; @@ -426,29 +426,28 @@ int main(int argc, char **argv) switch (mu) { case 1: - scs = 30000; - if (N_RB_DL == 217) { - fs = 122.88e6; - bw = 80e6; - - } - else if (N_RB_DL == 245) { - fs = 122.88e6; - bw = 90e6; - } - else if (N_RB_DL == 273) { - fs = 122.88e6; - bw = 100e6; - } - else if (N_RB_DL == 106) { - fs = 61.44e6; - bw = 40e6; - } - else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); - break; - - + scs = 30000; + frame_parms->Lmax = 8; + if (N_RB_DL == 217) { + fs = 122.88e6; + bw = 80e6; + } + else if (N_RB_DL == 245) { + fs = 122.88e6; + bw = 90e6; + } + else if (N_RB_DL == 273) { + fs = 122.88e6; + bw = 100e6; + } + else if (N_RB_DL == 106) { + fs = 61.44e6; + bw = 40e6; + } + else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + break; case 3: + frame_parms->Lmax = 64; scs = 120000; if (N_RB_DL == 66) { fs = 122.88e6; @@ -457,6 +456,7 @@ int main(int argc, char **argv) else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); break; } + // cfo with respect to sub-carrier spacing eps = cfo/scs; @@ -510,7 +510,6 @@ int main(int argc, char **argv) printf("Allocating %d samples for txdata\n",frame_length_complex_samples); txdata[i] = malloc(frame_length_complex_samples*sizeof(int)); bzero(r_re[i],frame_length_complex_samples*sizeof(int)); - } if (pbch_file_fd!=NULL) { @@ -536,60 +535,68 @@ int main(int argc, char **argv) } nr_gold_pbch(UE); + // generate signal if (input_fd==NULL) { - gNB->pbch_configured = 1; - - gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0; - for (int slot=0;slotslots_per_frame;slot++) { - for (aa=0; aaframe_parms.nb_antennas_tx; aa++) - memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t)); - - nr_common_signal_procedures (gNB,frame,slot); + for (i=0; iLmax; i++) { + if((SSB_positions >> i) & 0x01) { - for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { - if (cyclic_prefix_type == 1) { - PHY_ofdm_mod(gNB->common_vars.txdataF[aa], - &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], - frame_parms->ofdm_symbol_size, - 12, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); - } else { - /* nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], - &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], - 14, - frame_parms);*/ - PHY_ofdm_mod(gNB->common_vars.txdataF[aa], - (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], - frame_parms->ofdm_symbol_size, - 1, - frame_parms->nb_prefix_samples0, - CYCLIC_PREFIX); - - apply_nr_rotation(frame_parms, - (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], - slot, - 0, - 1, - frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0); - PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size], - (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+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][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size], - slot, - 1, - 13, - frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples); - } - } + gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33; + gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i; + + start_symbol = nr_get_ssb_start_symbol(frame_parms,i); + int slot = start_symbol/14; + + for (aa=0; aaframe_parms.nb_antennas_tx; aa++) + memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t)); + + nr_common_signal_procedures (gNB,frame,slot,gNB->ssb[i].ssb_pdu); + + for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { + if (cyclic_prefix_type == 1) { + PHY_ofdm_mod(gNB->common_vars.txdataF[aa], + &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], + frame_parms->ofdm_symbol_size, + 12, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + } else { + /*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], + &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], + 14, + frame_parms);*/ + PHY_ofdm_mod(gNB->common_vars.txdataF[aa], + (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], + frame_parms->ofdm_symbol_size, + 1, + frame_parms->nb_prefix_samples0, + CYCLIC_PREFIX); + + apply_nr_rotation(frame_parms, + (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], + slot, + 0, + 1, + frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0); + + PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size], + (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+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][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size], + slot, + 1, + 13, + frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples); + } + } + } } - LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); if (gNB->frame_parms.nb_antennas_tx>1) LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); @@ -598,9 +605,9 @@ int main(int argc, char **argv) printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0); UE->UE_fo_compensation = 1; // perform fo compensation when samples from file are used if (fread(txdata[0], - sizeof(int32_t), - frame_length_complex_samples, - input_fd) != frame_length_complex_samples) { + sizeof(int32_t), + frame_length_complex_samples, + input_fd) != frame_length_complex_samples) { printf("error reading from file\n"); //exit(-1); } @@ -684,17 +691,14 @@ int main(int argc, char **argv) UE->rx_offset=0; uint8_t ssb_index = 0; while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb - frame_parms->ssb_index = ssb_index; - UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms); + UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index); - int ssb_slot = (ssb_index>>1)+(n_hf*frame_parms->slots_per_frame); + int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1)); for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) { nr_slot_fep(UE, &proc, i%frame_parms->symbols_per_slot, - ssb_slot, - 0, - 0); + ssb_slot); 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); @@ -718,9 +722,9 @@ int main(int argc, char **argv) payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte); for (i=0;i<3;i++){ - payload_ret += (UE->pbch_vars[0]->decoded_output[i] == (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i))); + payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff)); } - //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->rx_ind.rx_indication_body->mib_pdu.additional_bits); + //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte); //printf("ret %d\n", payload_ret); if (payload_ret!=4) n_errors_payload++; diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 5f20650ced..1b3d8d680b 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -47,6 +47,7 @@ #include "OCG_vars.h" #include #include +//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" #define NR_PRACH_DEBUG 1 @@ -62,8 +63,8 @@ RU_t *ru; double cpuf; extern uint16_t prach_root_sequence_map0_3[838]; openair0_config_t openair0_cfg[MAX_CARDS]; -uint8_t nfapi_mode=0; -int sl_ahead = 0; +//uint8_t nfapi_mode=0; +uint16_t sl_ahead = 0; //void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe); @@ -71,6 +72,10 @@ int sl_ahead = 0; msc_interface_t msc_interface; uint64_t get_softmodem_optmask(void) {return 0;} softmodem_params_t *get_softmodem_params(void) {return 0;} +int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); } +int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); } +int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); } +int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); } void rrc_data_ind( @@ -128,13 +133,30 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;} +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) +{ + return; +} + +int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, + const int CC_id, + const uint8_t gNB_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *buffer_pP) +{ + 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) { +int nr_derive_key(int alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out) +{ return 0; } @@ -184,7 +206,7 @@ int main(int argc, char **argv){ randominit(0); - 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) { + while ((c = getopt (argc, argv, "hHaA:Cc:l: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"); @@ -197,6 +219,10 @@ int main(int argc, char **argv){ config_index = atoi(optarg); break; + case 'l': + loglvl = atoi(optarg); + break; + case 'r': msg1_frequencystart = atoi(optarg); break; @@ -444,7 +470,10 @@ int main(int argc, char **argv){ nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions); - uint64_t absoluteFrequencyPointA = (mu==1 ? 640000 : 2070833); + uint64_t absoluteFrequencyPointA = to_nrarfcn(frame_parms->nr_band, + frame_parms->dl_CarrierFreq, + frame_parms->numerology_index, + frame_parms->N_RB_UL*(180e3)*(1 << frame_parms->numerology_index)); uint8_t subframe = slot/frame_parms->slots_per_subframe; diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index a96a62f656..8d79633a6f 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -53,7 +53,7 @@ openair0_config_t openair0_cfg[MAX_CARDS]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; -uint8_t nfapi_mode = 0; +//uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3}; uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3}; diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index afebe4ed97..6f2af73a1d 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -60,7 +60,7 @@ uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3}; uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3}; double cpuf; -uint8_t nfapi_mode = 0; +//uint8_t nfapi_mode = 0; uint16_t NB_UE_INST = 1; // needed for some functions diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index fd2e1dc0b7..fce690ebd2 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -75,12 +75,14 @@ PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; -int sf_ahead=4 ; -int sl_ahead=0; +uint16_t sf_ahead=4 ; +int slot_ahead=6 ; +uint16_t sl_ahead=0; double cpuf; -uint8_t nfapi_mode = 0; +//uint8_t nfapi_mode = 0; uint64_t downlink_frequency[MAX_NUM_CCs][4]; +extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration 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; } @@ -154,7 +156,31 @@ 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) { +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) +{ + return; +} + +int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, + const int CC_id, + const uint8_t gNB_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *buffer_pP) +{ + return 0; +} + +//nFAPI P7 dummy functions + +int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); } +int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); } +int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); } +int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); } + +int nr_derive_key(int alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out) +{ return 0; } @@ -594,8 +620,8 @@ int main(int argc, char **argv) frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) - frame_parms->nb_antennas_tx = n_tx; - frame_parms->nb_antennas_rx = n_rx; + //frame_parms->nb_antennas_tx = n_tx; + //frame_parms->nb_antennas_rx = n_rx; frame_parms->N_RB_DL = N_RB_DL; frame_parms->N_RB_UL = N_RB_UL; frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; @@ -613,6 +639,7 @@ int main(int argc, char **argv) rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon)); NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon; + NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t)); NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup)); prepare_scc(rrc.carrier.servingcellconfigcommon); uint64_t ssb_bitmap; @@ -620,7 +647,10 @@ int main(int argc, char **argv) fix_scc(scc,ssb_bitmap); + prepare_scd(scd); + fill_default_secondaryCellGroup(scc, + scd, secondaryCellGroup, 0, 1, @@ -629,13 +659,16 @@ int main(int argc, char **argv) // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); + /* RRC parameter validation for secondaryCellGroup */ + fix_scd(scd); + AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration - rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); + rrc_mac_config_req_gNB(0,0,n_tx,n_rx,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0,0,1,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; @@ -1040,70 +1073,69 @@ int main(int argc, char **argv) } - nr_fill_ulsch(gNB,frame,slot,pusch_pdu); + //nr_fill_ulsch(gNB,frame,slot,pusch_pdu); // Not needed as its its already filled as apart of "nr_schedule_response(Sched_INFO);" for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff; if (input_fd == NULL) { - // set FAPI parameters for UE, put them in the scheduled response and call - nr_ue_scheduled_response(&scheduled_response); - - - /////////////////////////phy_procedures_nr_ue_TX/////////////////////// - /////////// - - phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id); - - - if (n_trials==1) { - LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1); - LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1); - } - /////////// - //////////////////////////////////////////////////// - tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); - - 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); + // set FAPI parameters for UE, put them in the scheduled response and call + nr_ue_scheduled_response(&scheduled_response); + + + /////////////////////////phy_procedures_nr_ue_TX/////////////////////// + /////////// + + phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id); + + + if (n_trials==1) { + LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1); + LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1); + } + /////////// + //////////////////////////////////////////////////// + tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); + + 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); } else n_trials = 1; if (input_fd == NULL ) { - sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; - sigma = pow(10,sigma_dB/10); + sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; + sigma = pow(10,sigma_dB/10); - 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)); + 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; icommon_vars.txdata[aa][slot_offset]))[(i<<1)]); - s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]); - } - } - + for (i=0; inb_antennas_rx; aa++) { + s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]); + s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]); + } + } - if (UE2gNB->max_Doppler == 0) { - multipath_channel(UE2gNB,s_re,s_im,r_re,r_im, - slot_length,0,(n_trials==1)?1:0); - } else { - multipath_tv_channel(UE2gNB,s_re,s_im,r_re,r_im, - 2*slot_length,0); - } - for (i=0; inb_antennas_rx; ap++) { - ((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))); + + if (UE2gNB->max_Doppler == 0) { + multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0); + } else { + multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0); + } + for (i=0; inb_antennas_rx; ap++) { + ((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)], &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1]); } - } - } + } + } - } + } /*End input_fd */ if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c index cc8c62a36d..4d17fe723c 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c @@ -142,6 +142,10 @@ void thread_top_init(char *thread_name, int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } +int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); } +int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); } +int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); } +int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); } int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c index d344992586..c68ce73758 100644 --- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c +++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c @@ -48,9 +48,9 @@ void multipath_tv_channel(channel_desc_t *desc, printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %g\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length, desc->max_Doppler); #endif - tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex)); - rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex)); - H_t= (double complex ** *) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **)); + tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex *)); + rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex *)); + H_t= (double complex ***) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **)); // tv_H_t = (double complex *) malloc(length*sizeof(double complex)); rx_temp= (double complex *) calloc(length,sizeof(double complex)); @@ -63,10 +63,10 @@ void multipath_tv_channel(channel_desc_t *desc, } for(i=0; inb_tx*desc->nb_rx; i++) { - H_t[i] = (double complex **) malloc(length*sizeof(double complex *)); + H_t[i] = (double complex **)malloc(desc->nb_taps*sizeof(double complex *)); - for(j=0; jnb_taps,sizeof(double complex)); + for(j=0; jnb_taps; j++) { + H_t[i][j] = (double complex *)calloc(length,sizeof(double complex)); } } @@ -116,7 +116,7 @@ void multipath_tv_channel(channel_desc_t *desc, free(rx); for(i=0; inb_rx*desc->nb_tx; i++) { - for(j=0; jnb_taps; j++) { free(H_t[i][j]); } @@ -131,14 +131,29 @@ void multipath_tv_channel(channel_desc_t *desc, void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){ int i,j,p,l,k; - double *alpha,*phi_rad,pi=acos(-1),*w_Hz; + double *alpha,***phi_rad,pi=acos(-1),***w_Hz; alpha = (double *)calloc(desc->nb_paths,sizeof(double)); - phi_rad = (double *)calloc(desc->nb_paths,sizeof(double)); - w_Hz = (double *)calloc(desc->nb_paths,sizeof(double)); + phi_rad = (double ***)malloc(desc->nb_rx*desc->nb_tx*sizeof(double **)); + w_Hz = (double ***)malloc(desc->nb_rx*desc->nb_tx*sizeof(double **)); - for(i=0; inb_paths; i++) { - w_Hz[i]=desc->max_Doppler*cos(frand_a_b(0,2*pi)); - phi_rad[i]=frand_a_b(0,2*pi); + for(i=0; inb_tx*desc->nb_rx; i++) { + phi_rad[i] = (double **) malloc(desc->nb_taps*sizeof(double *)); + w_Hz[i] = (double **) malloc(desc->nb_taps*sizeof(double *)); + for(j=0; jnb_taps; j++) { + phi_rad[i][j] = (double *) malloc(desc->nb_paths*sizeof(double)); + w_Hz[i][j] = (double *) malloc(desc->nb_paths*sizeof(double)); + } + } + + for(i=0; inb_tx*desc->nb_rx; i++) { + for (j = 0; jnb_taps; j++) { + for(k=0; knb_paths; k++) { + w_Hz[i][j][k] = desc->max_Doppler*cos(frand_a_b(0,2*M_PI)); + phi_rad[i][j][k] = frand_a_b(0,2*M_PI); + //printf("w_hz[%d][%d][%d]=f_d*cos(theta) = %f\n",i,j,k,w_Hz[i][j][k]); + //printf("phi_rad[%d][%d][%d] = %f\n",i,j,k,phi_rad[i][j][k]); + } + } } if(desc->ricean_factor == 1) { @@ -153,44 +168,34 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){ } } - /* - // This is the code when we only consider a SISO case - for(i=0;inb_taps;j++) - { - for(p=0;pnb_paths;p++) - { - H[i][j] += sqrt(desc->amps[j]/2)*alpha[p]*cexp(-I*(2*pi*w_Hz[p]*i*(1/(desc->sampling_rate*1e6))+phi_rad[p])); - } - } - } - for(j=0;jnb_paths;j++) - { - phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->sampling_rate)+phi_rad[j],2*pi); - } - */ - - // if MIMO + // SISO or MIMO for (i=0; inb_rx; i++) { for(j=0; jnb_tx; j++) { - for(k=0; knb_taps; l++) { - H[i+(j*desc->nb_rx)][k][l] = 0; - + for(k=0; knb_taps; k++) { + for(l=0; lnb_paths; p++) { - H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[l]/2)*alpha[p]*cexp(I*(2*pi*w_Hz[p]*k*(1/(desc->sampling_rate*1e6))+phi_rad[p])); + H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[k])*alpha[p]*cexp(I*(2*pi*w_Hz[i+(j*desc->nb_rx)][k][p]*l*(1/(desc->sampling_rate*1e6))+phi_rad[i+(j*desc->nb_rx)][k][p])); } } - } - - for(j=0; jnb_paths; j++) { - phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->sampling_rate)+phi_rad[j],2*pi); + //printf("H[tx%d][rx%d][k%d] = %f+j%f \n",j,i,k,creal(H[i+(j*desc->nb_rx)][k][0]),cimag(H[i+(j*desc->nb_rx)][k][0])); } } } - + //accumlate the phase + /*for(k=0; knb_taps; k++) { + * for(j=0; jnb_paths; j++) { + * desc->random_phase[k][j] = fmod(2*pi*w_Hz[k][j]*(length-1)*(1/(desc->sampling_rate*1e6))+phi_rad[k][j],2*pi); + * } + * }*/ free(alpha); + for(i=0; inb_rx*desc->nb_tx; i++) { + for (j=0; jnb_taps; j++) { + free(w_Hz[i][j]); + free(phi_rad[i][j]); + } + free(w_Hz[i]); + free(phi_rad[i]); + } free(w_Hz); free(phi_rad); } @@ -203,7 +208,7 @@ void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t for(i=0; i<((int)nb_samples-dd); i++) { for(j=0; jj) - y[i+dd] += creal(h[i][j])*creal(x[i-j])-cimag(h[i][j])*cimag(x[i-j]) + I*(creal(h[i][j])*cimag(x[i-j])+cimag(h[i][j])*creal(x[i-j])); + y[i+dd] += creal(h[j][i])*creal(x[i-j])-cimag(h[j][i])*cimag(x[i-j]) + I*(creal(h[j][i])*cimag(x[i-j])+cimag(h[j][i])*creal(x[i-j])); } } } diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 8c063fadc0..47597f4d6e 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -61,7 +61,7 @@ static telnetshell_vardef_t channelmod_vardef[] = { static double snr_dB=25; static double sinr_dB=0; static unsigned int max_chan; -static channel_desc_t** defined_channels; +static channel_desc_t **defined_channels; void fill_channel_desc(channel_desc_t *chan_desc, uint8_t nb_tx, uint8_t nb_rx, @@ -1185,11 +1185,11 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, 1); break; - case Rayleigh1: + case Rayleigh1://MIMO Test uses Rayleigh1 nb_taps = 1; Td = 0; channel_length = 1; - ricean_factor = 1; + ricean_factor = 0.0; aoa = .03; maxDoppler = 0; fill_channel_desc(chan_desc,nb_tx, @@ -1632,7 +1632,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, void free_channel_desc_scm(channel_desc_t *ch) { // Must be made cleanly, a lot of leaks... - defined_channels[ch->chan_idx]=NULL; + if (max_chan != 0) defined_channels[ch->chan_idx]=NULL; if(ch->free_flags&CHANMODEL_FREE_AMPS) free(ch->amps); for (int i = 0; inb_tx*ch->nb_rx; i++) { diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 02f878ee2e..64c42eaf0e 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -42,6 +42,7 @@ #include "LTE_SL-DiscResourcePool-r12.h" #include "NR_RACH-ConfigCommon.h" #include "NR_ServingCellConfigCommon.h" +#include "NR_ServingCellConfig.h" //-------------------------------------------------------------------------------------------// // Messages for RRC logging #if defined(DISABLE_ITTI_XER_PRINT) @@ -405,8 +406,10 @@ typedef struct NRRrcConfigurationReq_s { uint16_t mnc[PLMN_LIST_MAX_SIZE]; uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; NR_ServingCellConfigCommon_t *scc; + NR_ServingCellConfig_t *scd; int ssb_SubcarrierOffset; int pdsch_AntennaPorts; + int pusch_AntennaPorts; int pusch_TargetSNRx10; int pucch_TargetSNRx10; } gNB_RrcConfigurationReq; diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index f6b4f3c4e2..2151375686 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -155,6 +155,11 @@ typedef struct security_capabilities_s { uint16_t integrity_algorithms; } security_capabilities_t; +typedef struct nr_security_capabilities_s { + uint16_t encryption_algorithms; + uint16_t integrity_algorithms; +} nr_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’ stands for ‘Mobile Terminating’ and ‘mo’ for @@ -393,6 +398,11 @@ typedef struct s1ap_register_enb_req_s { /* Number of SCTP streams used for a mme association */ uint16_t sctp_in_streams; uint16_t sctp_out_streams; + uint16_t s1_setuprsp_wait_timer; + uint16_t s1_setupreq_wait_timer; + uint16_t s1_setupreq_count; + uint16_t sctp_req_timer; + uint16_t sctp_req_count; } s1ap_register_enb_req_t; //-------------------------------------------------------------------------------------------// @@ -538,6 +548,9 @@ typedef struct s1ap_initial_context_setup_req_s { uint8_t nb_of_e_rabs; /* list of e_rab to be setup by RRC layers */ e_rab_t e_rab_param[S1AP_MAX_E_RAB]; + + /* NR Security algorithms (if any, set to 0 if not present) */ + nr_security_capabilities_t nr_security_capabilities; } s1ap_initial_context_setup_req_t; typedef struct tai_plmn_identity_s { diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 0c55764d6e..f4911c47dc 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -338,7 +338,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s { /* used for RRC->X2AP in source eNB */ int rnti; - security_capabilities_t security_capabilities; + nr_security_capabilities_t security_capabilities; /* SgNB Security Key */ uint8_t kgnb[32]; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index eb09d26947..b53a6feda1 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2432,6 +2432,65 @@ int RCconfig_S1( "to\n" " tracking_area_code = 1; // no string!!\n" " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); + if(*ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr <= 0xffff) + { + S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr; + } + else + { + LOG_E(S1AP, + "s1setup_rsp_timer value in conf file is invalid (%d). Default value is set.\n", + *ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr); + S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = 5; + } + + if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr <= 0xffff) + { + S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr; + } + else + { + LOG_E(S1AP, + "s1setup_req_timer value in conf file is invalid (%d). Default value is set.\n", + *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr); + S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = 5; + } + + if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr <= 0xffff) + { + S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr; + } + else + { + LOG_E(S1AP, + "s1setup_req_count value in conf file is invalid (%d). Default value is set.\n", + *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr); + S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = 0xffff; + } + + if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr <= 0xffff) + { + S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = *ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr; + } + else + { + LOG_E(S1AP, + "sctp_req_timer value in conf file is invalid (%d). Default value is set.\n", + *ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr); + S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = 180; + } + + if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr <= 0xffff) + { + S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = *ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr; + } + else + { + LOG_E(S1AP, + "sctp_req_count value in conf file is invalid (%d). Default value is set.\n", + *ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr); + S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = 0xffff; + } config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) { diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index de7e0bbdad..f26863414c 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -214,6 +214,11 @@ typedef enum { #define ENB_CONFIG_STRING_X2 "enable_x2" #define ENB_CONFIG_STRING_ENB_M2 "enable_enb_m2" #define ENB_CONFIG_STRING_MCE_M2 "enable_mce_m2" +#define ENB_CONFIG_STRING_S1SETUP_RSP_TIMER "s1setup_rsp_timer" +#define ENB_CONFIG_STRING_S1SETUP_REQ_TIMER "s1setup_req_timer" +#define ENB_CONFIG_STRING_S1SETUP_REQ_COUNT "s1setup_req_count" +#define ENB_CONFIG_STRING_SCTP_REQ_TIMER "sctp_req_timer" +#define ENB_CONFIG_STRING_SCTP_REQ_COUNT "sctp_req_count" /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* cell configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -239,6 +244,11 @@ typedef enum { {ENB_CONFIG_STRING_X2, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_ENB_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_MCE_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_S1SETUP_RSP_TIMER, NULL, 0, uptr:NULL, defuintval:5, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_S1SETUP_REQ_TIMER, NULL, 0, uptr:NULL, defuintval:5, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_S1SETUP_REQ_COUNT, NULL, 0, uptr:NULL, defuintval:65535, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_SCTP_REQ_TIMER, NULL, 0, uptr:NULL, defuintval:180, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_SCTP_REQ_COUNT, NULL, 0, uptr:NULL, defuintval:65535, TYPE_UINT, 0}, \ } #define ENB_ENB_ID_IDX 0 @@ -261,6 +271,11 @@ typedef enum { #define ENB_ENABLE_X2 17 #define ENB_ENABLE_ENB_M2 18 #define ENB_ENABLE_MCE_M2 19 +#define ENB_S1SETUP_RSP_TIMER_IDX 20 +#define ENB_S1SETUP_REQ_TIMER_IDX 21 +#define ENB_S1SETUP_REQ_COUNT_IDX 22 +#define ENB_SCTP_REQ_TIMER_IDX 23 +#define ENB_SCTP_REQ_COUNT_IDX 24 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define ENBPARAMS_CHECK { \ diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index 1f1d076e9d..d05908e8ed 100644 --- a/openair2/GNB_APP/RRC_nr_paramsvalues.h +++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h @@ -211,6 +211,24 @@ #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} +/* Serving Cell Config Dedicated */ +#define GNB_CONFIG_STRING_SERVINGCELLCONFIGDEDICATED "servingCellConfigDedicated" +#define GNB_CONFIG_STRING_DLPTRSFREQDENSITY0_0 "dl_ptrsFreqDensity0_0" +#define GNB_CONFIG_STRING_DLPTRSFREQDENSITY1_0 "dl_ptrsFreqDensity1_0" +#define GNB_CONFIG_STRING_DLPTRSTIMEDENSITY0_0 "dl_ptrsTimeDensity0_0" +#define GNB_CONFIG_STRING_DLPTRSTIMEDENSITY1_0 "dl_ptrsTimeDensity1_0" +#define GNB_CONFIG_STRING_DLPTRSTIMEDENSITY2_0 "dl_ptrsTimeDensity2_0" +#define GNB_CONFIG_STRING_DLPTRSEPRERATIO_0 "dl_ptrsEpreRatio_0" +#define GNB_CONFIG_STRING_DLPTRSREOFFSET_0 "dl_ptrsReOffset_0" +#define GNB_CONFIG_STRING_ULPTRSFREQDENSITY0_0 "ul_ptrsFreqDensity0_0" +#define GNB_CONFIG_STRING_ULPTRSFREQDENSITY1_0 "ul_ptrsFreqDensity1_0" +#define GNB_CONFIG_STRING_ULPTRSTIMEDENSITY0_0 "ul_ptrsTimeDensity0_0" +#define GNB_CONFIG_STRING_ULPTRSTIMEDENSITY1_0 "ul_ptrsTimeDensity1_0" +#define GNB_CONFIG_STRING_ULPTRSTIMEDENSITY2_0 "ul_ptrsTimeDensity2_0" +#define GNB_CONFIG_STRING_ULPTRSREOFFSET_0 "ul_ptrsReOffset_0" +#define GNB_CONFIG_STRING_ULPTRSMAXPORTS_0 "ul_ptrsMaxPorts_0" +#define GNB_CONFIG_STRING_ULPTRSPOWER_0 "ul_ptrsPower_0" + /*--------------------------------------------------------------------------------------------------------------------*/ /* pdcch_ConfigSIB1 parameters */ /*--------------------------------------------------------------------------------------------------------------------*/ @@ -395,6 +413,26 @@ {GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,i64ptr:&scc->ss_PBCH_BlockPower,defint64val:20,TYPE_INT64,0}, \ {GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,defintval:-1,TYPE_INT64,0}} +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Serving Cell Config Dedicated configuration parameters */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +#define SCDPARAMS_DESC(scd) { \ +{GNB_CONFIG_STRING_DLPTRSFREQDENSITY0_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.array[0],defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_DLPTRSFREQDENSITY1_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.array[1],defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_DLPTRSTIMEDENSITY0_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[0],defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_DLPTRSTIMEDENSITY1_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[1],defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_DLPTRSTIMEDENSITY2_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[2],defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_DLPTRSEPRERATIO_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio,defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_DLPTRSREOFFSET_0,NULL,0,i64ptr:scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset,defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_ULPTRSFREQDENSITY0_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[0],defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_ULPTRSFREQDENSITY1_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[1],defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_ULPTRSTIMEDENSITY0_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[0],defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_ULPTRSTIMEDENSITY1_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[1],defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_ULPTRSTIMEDENSITY2_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[2],defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_ULPTRSREOFFSET_0,NULL,0,i64ptr:scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->resourceElementOffset,defint64val:-1,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_ULPTRSMAXPORTS_0,NULL,0,i64ptr:&scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->maxNrofPorts,defint64val:0,TYPE_INT64,0}, \ +{GNB_CONFIG_STRING_ULPTRSPOWER_0,NULL,0,i64ptr:&scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->ptrs_Power,defint64val:0,TYPE_INT64,0}} diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 77e4564632..b525e7edb7 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -147,8 +147,6 @@ void *gNB_app_task(void *args_p) LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__); - RCconfig_NR_L1(); - RCconfig_nr_macrlc(); LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 4581b969d2..cbd416c9af 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -164,6 +164,8 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { // scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB_SUL = CALLOC(1,sizeof(NR_RSRP_Range_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long)); + // 0 - ENABLE, 1 - DISABLE, hence explicitly setting to DISABLED. + *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t)); scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->present = NR_SetupRelease_PUSCH_ConfigCommon_PR_setup; scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUSCH_ConfigCommon)); @@ -292,6 +294,163 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) { } } +/* Function to allocate dedicated serving cell config strutures */ +void prepare_scd(NR_ServingCellConfig_t *scd) { + // Allocate downlink structures + + scd->downlinkBWP_ToAddModList = CALLOC(1, sizeof(*scd->downlinkBWP_ToAddModList)); + + // Downlink bandwidth part + NR_BWP_Downlink_t *bwp = calloc(1, sizeof(*bwp)); + bwp->bwp_Id = 1; + + // Allocate downlink dedicated bandwidth part and PDSCH structures + 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->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; + + // Allocate DL DMRS and PTRS configuration + 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)); + NR_DMRS_DownlinkConfig_t *NR_DMRS_DownlinkCfg = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup; + NR_DMRS_DownlinkCfg->phaseTrackingRS=CALLOC(1, sizeof(*NR_DMRS_DownlinkCfg->phaseTrackingRS)); + NR_DMRS_DownlinkCfg->phaseTrackingRS->present = NR_SetupRelease_PTRS_DownlinkConfig_PR_setup; + NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup = CALLOC(1, sizeof(*NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup)); + NR_PTRS_DownlinkConfig_t *NR_PTRS_DownlinkCfg = NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup; + NR_PTRS_DownlinkCfg->frequencyDensity = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->frequencyDensity)); + long *dl_rbs = CALLOC(2, sizeof(long)); + for (int i=0;i<2;i++) { + ASN_SEQUENCE_ADD(&NR_PTRS_DownlinkCfg->frequencyDensity->list, &dl_rbs[i]); + } + NR_PTRS_DownlinkCfg->timeDensity = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->timeDensity)); + long *dl_mcs = CALLOC(3, sizeof(long)); + for (int i=0;i<3;i++) { + ASN_SEQUENCE_ADD(&NR_PTRS_DownlinkCfg->timeDensity->list, &dl_mcs[i]); + } + NR_PTRS_DownlinkCfg->epre_Ratio = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->epre_Ratio)); + NR_PTRS_DownlinkCfg->resourceElementOffset = CALLOC(1, sizeof(*NR_PTRS_DownlinkCfg->resourceElementOffset)); + *NR_PTRS_DownlinkCfg->resourceElementOffset = 0; + ASN_SEQUENCE_ADD(&scd->downlinkBWP_ToAddModList->list,bwp); + + // Allocate uplink structures + + scd->uplinkConfig = CALLOC(1, sizeof(*scd->uplinkConfig)); + scd->uplinkConfig->uplinkBWP_ToAddModList = CALLOC(1, sizeof(*scd->uplinkConfig->uplinkBWP_ToAddModList)); + + NR_PUSCH_Config_t *pusch_Config = CALLOC(1, sizeof(*pusch_Config)); + + // Allocate UL DMRS and PTRS structures + pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB = CALLOC(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB)); + pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->present = NR_SetupRelease_DMRS_UplinkConfig_PR_setup; + pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = CALLOC(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup)); + NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; + NR_DMRS_UplinkConfig->phaseTrackingRS = CALLOC(1, sizeof(*NR_DMRS_UplinkConfig->phaseTrackingRS)); + NR_DMRS_UplinkConfig->phaseTrackingRS->present = NR_SetupRelease_PTRS_UplinkConfig_PR_setup; + NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup = CALLOC(1, sizeof(*NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup)); + NR_PTRS_UplinkConfig_t *NR_PTRS_UplinkConfig = NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup; + NR_PTRS_UplinkConfig->transformPrecoderDisabled = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled)); + NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity)); + long *n_rbs = CALLOC(2, sizeof(long)); + for (int i=0;i<2;i++) { + ASN_SEQUENCE_ADD(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity->list, &n_rbs[i]); + } + NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity)); + long *ptrs_mcs = CALLOC(3, sizeof(long)); + for (int i = 0; i < 3; i++) { + ASN_SEQUENCE_ADD(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity->list, &ptrs_mcs[i]); + } + NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = CALLOC(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset)); + *NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = 0; + + // UL bandwidth part + NR_BWP_Uplink_t *ubwp = CALLOC(1, sizeof(*ubwp)); + ubwp->bwp_Id = 1; + ubwp->bwp_Dedicated = CALLOC(1, sizeof(*ubwp->bwp_Dedicated)); + + ubwp->bwp_Dedicated->pusch_Config = CALLOC(1, sizeof(*ubwp->bwp_Dedicated->pusch_Config)); + ubwp->bwp_Dedicated->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup; + ubwp->bwp_Dedicated->pusch_Config->choice.setup = pusch_Config; + + ASN_SEQUENCE_ADD(&scd->uplinkConfig->uplinkBWP_ToAddModList->list,ubwp); +} + +/* This function checks dedicated serving cell configuration and performs fixes as needed */ +void fix_scd(NR_ServingCellConfig_t *scd) { + // Check for DL PTRS parameters validity + if (scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS) { + // If any of the frequencyDensity values are not set or are out of bounds, PTRS is assumed to be not present + for (int i = scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.count-1; i >= 0; i--) { + if ((*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.array[i] < 1) + || (*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.array[i] > 276)) { + LOG_I(RRC, "DL PTRS frequencyDensity %d not set. Assuming PTRS not present! \n", i); + free(scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS); + scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS = NULL; + break; + } + } + } + if (scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS) { + // If any of the timeDensity values are not set or are out of bounds, PTRS is assumed to be not present + for (int i = scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.count-1; i >= 0; i--) { + if ((*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[i] < 0) + || (*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[i] > 29)) { + LOG_I(RRC, "DL PTRS timeDensity %d not set. Assuming PTRS not present! \n", i); + free(scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS); + scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS = NULL; + break; + } + } + } + if (scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS) { + if (*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset > 2) { + LOG_I(RRC, "Freeing DL PTRS resourceElementOffset \n"); + free(scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset); + scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset = NULL; + } + if (*scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio > 1) { + LOG_I(RRC, "Freeing DL PTRS epre_Ratio \n"); + free(scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio); + scd->downlinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio = NULL; + } + } + + if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { + // If any of the frequencyDensity values are not set or are out of bounds, PTRS is assumed to be not present + for (int i = scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.count-1; i >= 0; i--) { + if ((*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[i] < 1) + || (*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[i] > 276)) { + LOG_I(RRC, "UL PTRS frequencyDensity %d not set. Assuming PTRS not present! \n", i); + free(scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS); + scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS = NULL; + break; + } + } + } + + if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { + // If any of the timeDensity values are not set or are out of bounds, PTRS is assumed to be not present + for (int i = scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.count-1; i >= 0; i--) { + if ((*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[i] < 0) + || (*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[i] > 29)) { + LOG_I(RRC, "UL PTRS timeDensity %d not set. Assuming PTRS not present! \n", i); + free(scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS); + scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS = NULL; + break; + } + } + } + if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS) { + // Check for UL PTRS parameters validity + if (*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->resourceElementOffset > 2) { + LOG_I(RRC, "Freeing UL PTRS resourceElementOffset \n"); + free(scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->resourceElementOffset); + scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->resourceElementOffset = NULL; + } + } +} + void RCconfig_nr_flexran() { uint16_t i; @@ -423,15 +582,17 @@ void RCconfig_NR_L1(void) { RC.nb_nr_CC = (int *)malloc((1+RC.nb_nr_inst)*sizeof(int)); RC.nb_nr_CC[0]=1; - RC.nb_nr_inst =1; // DJP - feptx_prec uses num_gNB but phy_init_RU uses nb_nr_inst - LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_nr_inst=1 this is because phy_init_RU() uses that to index and not RC.num_gNB - why the 2 similar variables?\n", __FUNCTION__); LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_nr_CC[0]=%d for init_gNB_afterRU()\n", __FUNCTION__, RC.nb_nr_CC[0]); LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_nr_macrlc_inst:%d because used by mac_top_init_gNB()\n", __FUNCTION__, RC.nb_nr_macrlc_inst); mac_top_init_gNB(); - configure_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, RC.gNB[j]->eth_params_n.remote_portc, RC.gNB[j]->eth_params_n.my_addr, RC.gNB[j]->eth_params_n.my_portd, RC.gNB[j]->eth_params_n .remote_portd); + configure_nr_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, + RC.gNB[j]->eth_params_n.remote_portc, + RC.gNB[j]->eth_params_n.my_addr, + RC.gNB[j]->eth_params_n.my_portd, + RC.gNB[j]->eth_params_n.remote_portd); }else { // other midhaul } }// for (j = 0; j < RC.nb_nr_L1_inst; j++) @@ -501,8 +662,8 @@ void RCconfig_nr_macrlc() { //sf_ahead = 2; // Cannot cope with 4 subframes between RX and TX - set it to 2 - printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); - configure_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc); + printf("**************** vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc); + configure_nr_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc); printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc); }else { // other midhaul AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); @@ -514,6 +675,101 @@ void RCconfig_nr_macrlc() { } +void config_security(gNB_RRC_INST *rrc) +{ + paramdef_t logparams_defaults[] = SECURITY_GLOBALPARAMS_DESC; + int ret = config_get(logparams_defaults, + sizeof(logparams_defaults) / sizeof(paramdef_t), + CONFIG_STRING_SECURITY); + int i; + + if (ret < 0) { + LOG_W(RRC, "configuration file does not contain a \"security\" section, applying default parameters (no security)\n"); + rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */ + rrc->security.ciphering_algorithms_count = 1; + rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */ + rrc->security.integrity_algorithms_count = 1; + return; + } + + if (logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt > 4) { + LOG_E(RRC, "too much ciphering algorithms in section \"security\" of the configuration file, maximum is 4\n"); + exit(1); + } + if (logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt > 4) { + LOG_E(RRC, "too much integrity algorithms in section \"security\" of the configuration file, maximum is 4\n"); + exit(1); + } + + /* get ciphering algorithms */ + rrc->security.ciphering_algorithms_count = 0; + for (i = 0; i < logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt; i++) { + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea0")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 0; + rrc->security.ciphering_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea1")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 1; + rrc->security.ciphering_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea2")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 2; + rrc->security.ciphering_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea3")) { + rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 3; + rrc->security.ciphering_algorithms_count++; + continue; + } + LOG_E(RRC, "unknown ciphering algorithm \"%s\" in section \"security\" of the configuration file\n", + logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i]); + exit(1); + } + + /* get integrity algorithms */ + rrc->security.integrity_algorithms_count = 0; + for (i = 0; i < logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt; i++) { + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia0")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 0; + rrc->security.integrity_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia1")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 1; + rrc->security.integrity_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia2")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 2; + rrc->security.integrity_algorithms_count++; + continue; + } + if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia3")) { + rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 3; + rrc->security.integrity_algorithms_count++; + continue; + } + LOG_E(RRC, "unknown integrity algorithm \"%s\" in section \"security\" of the configuration file\n", + logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i]); + exit(1); + } + + if (rrc->security.ciphering_algorithms_count == 0) { + LOG_W(RRC, "no preferred ciphering algorithm set in configuration file, applying default parameters (no security)\n"); + rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */ + rrc->security.ciphering_algorithms_count = 1; + } + + if (rrc->security.integrity_algorithms_count == 0) { + LOG_W(RRC, "no preferred integrity algorithm set in configuration file, applying default parameters (no security)\n"); + rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */ + rrc->security.integrity_algorithms_count = 1; + } +} + void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { int num_gnbs = 0; @@ -531,6 +787,13 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { prepare_scc(scc); paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc); paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0}; + + // Serving Cell Config Dedicated + NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t)); + memset((void*)scd,0,sizeof(NR_ServingCellConfig_t)); + prepare_scd(scd); + paramdef_t SCDsParams[] = SCDPARAMS_DESC(scd); + paramlist_def_t SCDsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGDEDICATED, NULL, 0}; ////////// Physical parameters @@ -604,6 +867,23 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { (int)scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower); fix_scc(scc,ssb_bitmap); } + + sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); + + config_getlist(&SCDsParamList, NULL, 0, aprefix); + if (SCDsParamList.numelt > 0) { + sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_SERVINGCELLCONFIGDEDICATED, 0); + config_get( SCDsParams,sizeof(SCDsParams)/sizeof(paramdef_t),aprefix); + LOG_I(RRC,"Read in ServingCellConfigDedicated UL (FreqDensity_0 %d, FreqDensity_1 %d, TimeDensity_0 %d, TimeDensity_1 %d, TimeDensity_2 %d, RE offset %d \n", + (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[0], + (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->frequencyDensity->list.array[1], + (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[0], + (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[1], + (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->timeDensity->list.array[2], + (int)*scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup->transformPrecoderDisabled->resourceElementOffset); + } + fix_scd(scd); + printf("NRRRC %d: Southbound Transport %s\n",i,*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr)); if (strcmp(*(GNBParamList.paramarray[i][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) { @@ -669,18 +949,21 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = *GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr; printf("pdsch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr); NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr; + printf("pusch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_ANTENNAPORTS_IDX].iptr); + NRRRC_CONFIGURATION_REQ (msg_p).pusch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PUSCH_ANTENNAPORTS_IDX].iptr; printf("pusch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr); NRRRC_CONFIGURATION_REQ (msg_p).pusch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr; printf("pucch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr); NRRRC_CONFIGURATION_REQ (msg_p).pucch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr; NRRRC_CONFIGURATION_REQ (msg_p).scc = scc; + NRRRC_CONFIGURATION_REQ (msg_p).scd = scd; }// }//End for (k=0; k 0) - + config_security(rrc); }//End RCconfig_NRRRC function int RCconfig_nr_gtpu(void ) { diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index f1fe0c97c9..8b326d58c9 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -115,6 +115,7 @@ typedef enum { #define GNB_CONFIG_STRING_REMOTE_S_PORTD "remote_s_portd" #define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset" #define GNB_CONFIG_STRING_PDSCHANTENNAPORTS "pdsch_AntennaPorts" +#define GNB_CONFIG_STRING_PUSCHANTENNAPORTS "pusch_AntennaPorts" #define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10" #define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10" @@ -139,6 +140,7 @@ typedef enum { {GNB_CONFIG_STRING_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET, NULL, 0, iptr:NULL, defintval:31, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_PUSCHANTENNAPORTS, NULL, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PUSCHTARGETPOWX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PUCCHTARGETPOWX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ } @@ -159,8 +161,9 @@ typedef enum { #define GNB_REMOTE_S_PORTD_IDX 13 #define GNB_SSB_SUBCARRIEROFFSET_IDX 14 #define GNB_PDSCH_ANTENNAPORTS_IDX 15 -#define GNB_PUSCH_TARGETPOW_X10_IDX 16 -#define GNB_PUCCH_TARGETPOW_X10_IDX 17 +#define GNB_PUSCH_ANTENNAPORTS_IDX 16 +#define GNB_PUSCH_TARGETPOW_X10_IDX 17 +#define GNB_PUCCH_TARGETPOW_X10_IDX 18 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define GNBPARAMS_CHECK { \ @@ -452,4 +455,27 @@ typedef enum { #define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n" #define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n" /*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + + +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* security configuration */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CONFIG_STRING_SECURITY "security" + +#define SECURITY_CONFIG_CIPHERING "ciphering_algorithms" +#define SECURITY_CONFIG_INTEGRITY "integrity_algorithms" + +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* security configuration */ +/* optname help paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define SECURITY_GLOBALPARAMS_DESC { \ + {SECURITY_CONFIG_CIPHERING, "preferred ciphering algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \ + {SECURITY_CONFIG_INTEGRITY, "preferred integrity algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \ +} + +#define SECURITY_CONFIG_CIPHERING_IDX 0 +#define SECURITY_CONFIG_INTEGRITY_IDX 1 +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + #endif diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 1bae590a59..ae8522bc83 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -490,7 +490,7 @@ typedef struct { /*! \brief Uplink SCH PDU Structure */ typedef struct { - int8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */ + uint8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */ uint16_t Pdu_size; } __attribute__ ((__packed__)) ULSCH_PDU; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 381dce11b2..67cf5051ef 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -36,6 +36,7 @@ #include #include #include +#include #define TABLE_38213_13_1_NUM_INDEXES 15 #define TABLE_38213_13_2_NUM_INDEXES 14 @@ -418,14 +419,6 @@ typedef enum { 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, @@ -462,6 +455,7 @@ typedef struct Type0_PDCCH_CSS_config_s { uint32_t ssb_length; uint32_t ssb_index; uint32_t cset_start_rb; + bool active; } 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 8dc261df1d..941bd04877 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -31,10 +31,18 @@ */ #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include "common/utils/nr/nr_common.h" #include #define reserved 0xffff +// start symbols for SSB types A,B,C,D,E +uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50}; +uint16_t symbol_ssb_BD[64]={4,8,16,20,32,36,44,48,60,64,72,76,88,92,100,104,144,148,156,160,172,176,184,188,200,204,212,216,228,232,240,244,284,288, + 296,300,312,316,324,328,340,344,352,356,368,372,380,384,424,428,436,440,452,456,464,468,480,484,492,496,508,512,520,524}; +uint16_t symbol_ssb_E[64]={8,12,16,20,32,36,40,44,64,68,72,76,88,92,96,100,120,124,128,132,144,148,152,156,176,180,184,188,200,204,208,212,288,292, + 296,300,312,316,320,324,344,348,352,356,368,372,376,380,400,404,408,412,424,428,432,436,456,460,464,468,480,484,488,492}; + 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 @@ -1220,6 +1228,11 @@ int get_nr_prach_occasion_info_from_index(uint8_t index, 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]; + for(int i = 0; i < 64 ; i++) { + if ( (s_map >> i) & 0x01) { + (*N_RA_sfn)++; + } + } *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]; @@ -1396,19 +1409,17 @@ int get_nr_prach_info_from_index(uint8_t index, 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 %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); + 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; } @@ -1429,6 +1440,11 @@ int get_nr_prach_info_from_index(uint8_t index, if ( (table_6_3_3_2_2_prachConfig_Index[index][6] <= 1) && (slot%2 == 0) ) return 0; // no prach in even slots @ 30kHz for 1 prach per subframe } + for(int i = 0; i <= subframe ; i++) { + if ( (s_map >> i) & 0x01) { + (*RA_sfn_index)++; + } + } 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]; @@ -1567,79 +1583,6 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, } } -// 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}, - {3, 1710000, 1785000, 1805000, 1880000, 20, 361000, 100}, - {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, 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}, - {74, 1427000, 1470000, 1475000, 1518000, 20, 295000, 100}, - {75, 000, 000, 1432000, 1517000, 20, 286400, 100}, - {76, 000, 000, 1427000, 1432000, 20, 285400, 100}, - {77, 3300000, 4200000, 3300000, 4200000, 1, 620000, 15}, - {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, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15}, - {79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30}, - {80, 1710000, 1785000, 000, 000, 20, 342000, 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}, - {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} -}; - - // TS 38.211 Table 6.4.1.1.3-3: PUSCH DMRS positions l' within a slot for single-symbol DMRS and intra-slot frequency hopping disabled. // The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B. // When l' = l0, it is represented by 1 @@ -1680,11 +1623,9 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = { {1, 1025, -1, -1, 1, 513, -1, -1}, //14 // (DMRS l' position) }; -#define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t)) - // Returns the corresponding row index of the NR table -int get_nr_table_idx(int nr_bandP, uint8_t scs_index){ - +int get_nr_table_idx(int nr_bandP, uint8_t scs_index) +{ int i, j; int scs_khz = 15 << scs_index; int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95}; @@ -1695,8 +1636,8 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index){ AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]); } - 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++); + 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++); // selection of correct Deltaf raster according to SCS if ((nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) @@ -1705,35 +1646,33 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index){ 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); return i; - } // 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){ - +int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index) +{ 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); + int32_t 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); + LOG_I(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); + return delta_duplex; } -void get_frame_type(uint16_t current_band, - uint8_t scs_index, - lte_frame_type_t *current_type){ +lte_frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index) +{ + lte_frame_type_t current_type; + int32_t delta_duplex = get_delta_duplex(current_band, scs_index); - int32_t current_offset; - get_delta_duplex(current_band, scs_index, ¤t_offset); - - current_offset *= 1000; - if (current_offset == 0) - *current_type = TDD; + if (delta_duplex == 0) + current_type = TDD; else - *current_type = FDD; + 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); + LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex); + return current_type; } uint16_t config_bandwidth(int mu, int nb_rb, int nr_band) @@ -1911,7 +1850,6 @@ uint64_t from_nrarfcn(int nr_bandP, int deltaFglobal = 5; uint32_t N_REF_Offs = 0; uint64_t F_REF_Offs_khz = 0; - int32_t delta_duplex; uint64_t N_OFFs, frequency, freq_min; int i = get_nr_table_idx(nr_bandP, scs_index); @@ -1926,7 +1864,7 @@ uint64_t from_nrarfcn(int nr_bandP, F_REF_Offs_khz = 24250080; } - get_delta_duplex(nr_bandP, scs_index, &delta_duplex); + int32_t delta_duplex = get_delta_duplex(nr_bandP, scs_index); if (delta_duplex <= 0){ // DL band >= UL band if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL @@ -2342,7 +2280,7 @@ uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint mcs4 = 28; if (I_mcs < mcs1) { - LOG_I(PHY, "PUSH PT-RS is not present.\n"); + LOG_D(PHY, "PUSH PT-RS is not present.\n"); return -1; } else if (I_mcs >= mcs1 && I_mcs < mcs2) return 2; @@ -2372,7 +2310,7 @@ uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) { if (N_RB < nrb0) { - LOG_I(PHY,"PUSH PT-RS is not present.\n"); + LOG_D(PHY,"PUSH PT-RS is not present.\n"); return -1; } else if (N_RB >= nrb0 && N_RB < nrb1) return 2; @@ -2836,11 +2774,15 @@ int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) { else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); } -int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) { +int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slot, lte_frame_type_t frame_type) { int period,period1,period2=0; - if (scc->tdd_UL_DL_ConfigurationCommon==NULL) return(1); + // Note: condition on frame_type + // goal: the UL scheduler assumes mode is TDD therefore this hack is needed to make FDD work + if (scc->tdd_UL_DL_ConfigurationCommon == NULL || frame_type == FDD) { + return(1); + } if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 && scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530) @@ -3064,59 +3006,67 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config, valid = false; return valid; } - //printf("[MAC] PTRS is set K= %u L= %u\n", *K_ptrs,1<<*L_ptrs); + + /* Moved below check from scheduler function to here */ + if (*L_ptrs >= NrOfSymbols) { + valid = false; + return valid; + } 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 +uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb) { + + switch (scs) { + case NR_SubcarrierSpacing_kHz15: + return symbol_ssb_AC[i_ssb]; //type A + case NR_SubcarrierSpacing_kHz30: + if (band == 5 || band == 66) + return symbol_ssb_BD[i_ssb]; //type B + else + return symbol_ssb_AC[i_ssb]; //type C + case NR_SubcarrierSpacing_kHz120: + return symbol_ssb_BD[i_ssb]; //type D + case NR_SubcarrierSpacing_kHz240: + return symbol_ssb_E[i_ssb]; + default: + AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",scs); + } } -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) { +void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, + frame_t frameP, + NR_MIB_t *mib, + uint8_t num_slot_per_frame, + uint8_t ssb_subcarrier_offset, + uint16_t ssb_start_symbol, + NR_SubcarrierSpacing_t scs_ssb, + frequency_range_t frequency_range, + 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; + NR_SubcarrierSpacing_t scs_pdcch; + + channel_bandwidth_t min_channel_bw = bw_10MHz; // TODO remove hardcoding and implement Table 5.3.5-1 in 38.104 + + if (frequency_range == FR2) { + if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60) + scs_pdcch = NR_SubcarrierSpacing_kHz60; + else + scs_pdcch = NR_SubcarrierSpacing_kHz120; + } + else { + frequency_range = FR1; + if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60) + scs_pdcch = NR_SubcarrierSpacing_kHz15; + else + scs_pdcch = NR_SubcarrierSpacing_kHz30; + } - 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); + type0_PDCCH_CSS_config->frame = frameP; - 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; - } + uint8_t ssb_slot = ssb_start_symbol/14; uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13 uint32_t index_4msb = (mib->pdcch_ConfigSIB1.controlResourceSetZero); @@ -3127,8 +3077,8 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC type0_PDCCH_CSS_config->rb_offset = -1; // type0-pdcch coreset - switch( (scs_ssb << 5) | scs_pdcch ){ - case (scs_15kHz << 5) | scs_15kHz : + switch( (scs_ssb << 3) | scs_pdcch ){ + case (NR_SubcarrierSpacing_kHz15 << 5) | NR_SubcarrierSpacing_kHz15: 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]; @@ -3136,7 +3086,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC type0_PDCCH_CSS_config->rb_offset = table_38213_13_1_c4[index_4msb]; break; - case (scs_15kHz << 5) | scs_30kHz: + case (NR_SubcarrierSpacing_kHz15 << 3) | NR_SubcarrierSpacing_kHz30: 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]; @@ -3144,7 +3094,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC type0_PDCCH_CSS_config->rb_offset = table_38213_13_2_c4[index_4msb]; break; - case (scs_30kHz << 5) | scs_15kHz: + case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz15: 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; @@ -3161,7 +3111,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC break; - case (scs_30kHz << 5) | scs_30kHz: + case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz30: 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]; @@ -3177,7 +3127,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC }else{ ; } break; - case (scs_120kHz << 5) | scs_60kHz: + case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz60: 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; @@ -3194,7 +3144,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC } break; - case (scs_120kHz << 5) | scs_120kHz: + case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz120: 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; @@ -3211,7 +3161,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC } break; - case (scs_240kHz << 5) | scs_60kHz: + case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz60: 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]; @@ -3219,7 +3169,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC type0_PDCCH_CSS_config->rb_offset = table_38213_13_9_c4[index_4msb]; break; - case (scs_240kHz << 5) | scs_120kHz: + case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz120: 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; @@ -3290,7 +3240,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC 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); + uint32_t temp = (uint32_t)(big_o*(1<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; @@ -3326,12 +3276,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC /// MUX PATTERN 2 if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 2){ - if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){ + if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz60)){ // 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); + type0_PDCCH_CSS_config->n_c = ssb_slot; switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4 case 0: type0_PDCCH_CSS_config->first_symbol_index = 0; @@ -3348,12 +3298,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC default: break; } - }else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){ + }else if((scs_ssb == NR_SubcarrierSpacing_kHz240) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){ // 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); + type0_PDCCH_CSS_config->n_c = ssb_slot; switch(type0_PDCCH_CSS_config->ssb_index & 0x7){ // ssb_index(i) mod 8 case 0: type0_PDCCH_CSS_config->first_symbol_index = 0; @@ -3369,11 +3319,11 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC 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; + type0_PDCCH_CSS_config->n_c = ssb_slot - 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; + type0_PDCCH_CSS_config->n_c = ssb_slot - 1; break; case 6: type0_PDCCH_CSS_config->first_symbol_index = 0; @@ -3390,12 +3340,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC /// MUX PATTERN 3 if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 3){ - if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){ + if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){ // 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); + type0_PDCCH_CSS_config->n_c = ssb_slot; switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4 case 0: type0_PDCCH_CSS_config->first_symbol_index = 4; @@ -3432,8 +3382,83 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC 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->n_0 = ((uint32_t)(big_o*(1<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; } + +/* extract UL PTRS values from RRC and validate it based upon 38.214 6.2.3 */ +bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config, + uint16_t rbSize,uint8_t mcsIndex, uint8_t mcsTable, + uint8_t *K_ptrs, uint8_t *L_ptrs, + uint8_t *reOffset, uint8_t *maxNumPorts, uint8_t *ulPower, + uint8_t NrOfSymbols) +{ + bool valid = true; + + /* as defined in T 38.214 6.2.3 */ + if(rbSize < 3) { + valid = false; + return valid; + } + /* Check for Frequency Density values */ + if(ul_ptrs_config->transformPrecoderDisabled->frequencyDensity->list.count < 2) { + /* Default value for K_PTRS = 2 as defined in T 38.214 6.2.3 */ + *K_ptrs = 2; + } + else { + *K_ptrs = get_K_ptrs(*ul_ptrs_config->transformPrecoderDisabled->frequencyDensity->list.array[0], + *ul_ptrs_config->transformPrecoderDisabled->frequencyDensity->list.array[1], + rbSize); + } + /* Check for time Density values */ + if(ul_ptrs_config->transformPrecoderDisabled->timeDensity->list.count < 3) { + *L_ptrs = 0; + } + else { + *L_ptrs = get_L_ptrs(*ul_ptrs_config->transformPrecoderDisabled->timeDensity->list.array[0], + *ul_ptrs_config->transformPrecoderDisabled->timeDensity->list.array[1], + *ul_ptrs_config->transformPrecoderDisabled->timeDensity->list.array[2], + mcsIndex, + mcsTable); + } + + *reOffset = *ul_ptrs_config->transformPrecoderDisabled->resourceElementOffset; + *maxNumPorts = ul_ptrs_config->transformPrecoderDisabled->maxNrofPorts; + *ulPower = ul_ptrs_config->transformPrecoderDisabled->ptrs_Power; + /* If either or both of the parameters PT-RS time density (LPT-RS) and PT-RS frequency density (KPT-RS), shown in Table + * 6.2.3.1-1 and Table 6.2.3.1-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 PUSCH 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 PUSCH with allocation duration of 2 symbols as defined in Clause 6.4.1.2.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; + } + + /* Moved below check from nr_ue_scheduler function to here */ + if (*L_ptrs >= NrOfSymbols) { + valid = false; + return valid; + } + return valid; +} + diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 58ecd54733..741b4e4799 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -39,9 +39,9 @@ uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); -void get_frame_type(uint16_t nr_bandP, uint8_t scs_index, lte_frame_type_t *current_type); +lte_frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index); -void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex); +int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index); uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); @@ -51,7 +51,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); -int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); +int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slotP, lte_frame_type_t frame_type); uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc, const NR_CellGroupConfig_t *secondaryCellGroup, @@ -81,7 +81,7 @@ int get_nr_prach_info_from_index(uint8_t index, uint8_t *N_dur, uint16_t *RA_sfn_index, uint8_t *N_RA_slot, - uint8_t *config_period); + uint8_t *config_period); int get_nr_prach_occasion_info_from_index(uint8_t index, uint32_t pointa, @@ -126,12 +126,18 @@ 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); +void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, + frame_t frameP, + NR_MIB_t *mib, + uint8_t num_slot_per_frame, + uint8_t ssb_subcarrier_offset, + uint16_t ssb_start_symbol, + NR_SubcarrierSpacing_t scs_ssb, + frequency_range_t frequency_range, + uint32_t ssb_index, + uint32_t ssb_offset_point_a); + +uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb); int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH); @@ -141,6 +147,11 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config, uint8_t *nERatio,uint8_t *reOffset, uint8_t NrOfSymbols); +bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config, + uint16_t rbSize,uint8_t mcsIndex, uint8_t mcsTable, + uint8_t *K_ptrs, uint8_t *L_ptrs, + uint8_t *reOffset, uint8_t *maxNumPorts, uint8_t *ulPower, + 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 diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index f6bd5436bc..fee2efc4a8 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -203,13 +203,12 @@ 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; - get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type); + mac->frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); // cell config cfg->cell_config.phy_cell_id = *scc->physCellId; - cfg->cell_config.frame_duplex_type = frame_type; + cfg->cell_config.frame_duplex_type = mac->frame_type; // SSB config cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower; @@ -313,7 +312,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,frequency_range); + 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, mac->frame_type, frequency_range); //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ??? } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index dd0aa15c52..933286f95a 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -318,13 +318,15 @@ typedef struct { NR_TAG_Config_t *tag_Config; NR_PHR_Config_t *phr_Config; NR_RNTI_Value_t *cs_RNTI; - NR_MIB_t *mib; + NR_MIB_t *mib; NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP]; NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP]; NR_ControlResourceSet_t *coreset[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP]; NR_SearchSpace_t *SSpace[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP][FAPI_NR_MAX_SS_PER_CORESET]; + lte_frame_type_t frame_type; + /*BWP*/ // dedicated active DL BWP NR_BWP_Id_t DL_BWP_Id; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index c4909c1384..14d1ea63fb 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -56,14 +56,14 @@ int8_t nr_ue_decode_mib( void *pduP, uint16_t cell_id ); -/**\brief decode sib1 pdu in NR_UE, from if_module dl_ind +/**\brief decode SIB1 and other SIs pdus 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, +int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_vars.c b/openair2/LAYER2/NR_MAC_UE/mac_vars.c index ecabdb870c..383267090f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_vars.c +++ b/openair2/LAYER2/NR_MAC_UE/mac_vars.c @@ -32,7 +32,7 @@ #include -const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC"}; +const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC", "NR_RNTI_SP_CSI", "NR_RNTI_SI"}; const char *dci_formats[]={"1_0", "1_1", "2_0", "2_1", "2_2", "2_3", "0_0", "0_1"}; // 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 diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index b4b63e0064..8f234cb585 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -35,6 +35,7 @@ /* RRC */ #include "NR_RACH-ConfigCommon.h" +#include "RRC/NR_UE/rrc_proto.h" /* PHY */ #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" @@ -514,7 +515,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, 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, mac_ce_len; + int num_sdus = 0; + int offset = 0; // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side if (!prach_resources->init_msg1) { @@ -532,36 +534,27 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, 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; + uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); + payload = (uint8_t*) mac->CCCH_pdu.payload; + num_sdus = 1; post_padding = 1; + sdu_lcids[0] = lcid; - if (0){ - // initialisation by RRC - // CCCH PDU - // size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id, - // CC_id, - // frame, - // CCCH, - // 1, - // mac_sdus, - // gNB_id, - // 0); - LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu); - } else { - // fill ulsch_buffer with random data - for (int i = 0; i < TBS_bytes; i++){ - mac_sdus[i] = (unsigned char) (lrand48()&0xff); - } - //Sending SDUs with size 1 - //Initialize elements of sdu_lcids and sdu_lengths - sdu_lcids[0] = lcid; - sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len; - header_length_total += 2 + (sdu_lengths[0] >= 128); - size_sdu += sdu_lengths[0]; + // initialisation by RRC + + // TODO: To be removed after RA procedures fully implemented + if(get_softmodem_params()->do_ra) { + nr_rrc_ue_generate_RRCSetupRequest(mod_id,gNB_id); } + // CCCH PDU + size_sdu = (uint16_t) nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, mac_sdus); + + sdu_lengths[0] = size_sdu; + + LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu); + if (size_sdu > 0) { LOG_D(MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx); @@ -589,12 +582,27 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, post_padding, 0); + AssertFatal(TBS_max > offset, "Frequency resources are not enough for Msg3!\n"); + // Padding: fill remainder with 0 if (post_padding > 0){ - for (int j = 0; j < (TBS_bytes - offset); j++) - payload[offset + j] = 0; // mac_pdu[offset + j] = 0; + for (int j = 0; j < (TBS_max - offset); j++) + payload[offset + j] = 0; } - } + } + + LOG_D(MAC,"size_sdu = %i\n", size_sdu); + LOG_D(MAC,"offset = %i\n", offset); + for(int k = 0; k < TBS_max; k++) { + LOG_D(MAC,"(%i): %i\n", k, prach_resources->Msg3[k]); + } + + // Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after + // receiving Msg2 (which contains the Msg3 resource reserve). + // Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s. + mac->ulsch_pdu.Pdu_size = TBS_max; + memcpy(mac->ulsch_pdu.payload, prach_resources->Msg3, TBS_max); + } else if (ra->RA_window_cnt != -1) { // RACH is active 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); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 64067e9d60..8b8fc4e0c2 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -101,10 +101,11 @@ int8_t nr_ue_decode_mib(module_id_t module_id, void *pduP, uint16_t cell_id) { - LOG_I(MAC,"[L2][MAC] decode mib\n"); + LOG_D(MAC,"[L2][MAC] decode mib\n"); NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - + NR_ServingCellConfigCommon_t *scc = mac->scc; + frequency_range_t frequency_range; nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n"); @@ -120,9 +121,11 @@ int8_t nr_ue_decode_mib(module_id_t module_id, frame = frame << 4; frame = frame | frame_number_4lsb; if(ssb_length == 64){ + frequency_range = FR2; for (int i=0; i<3; i++) ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i)); }else{ + frequency_range = FR1; if(ssb_subcarrier_offset_msb){ ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10; } @@ -141,26 +144,50 @@ int8_t nr_ue_decode_mib(module_id_t module_id, //storing ssb index in the mac structure mac->mib_ssb = ssb_index; - 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); + if (get_softmodem_params()->sa == 1) { + + // TODO these values shouldn't be taken from SCC in SA + uint8_t scs_ssb = *scc->ssbSubcarrierSpacing; + uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + int scs_scaling = 1<downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000) + scs_scaling = scs_scaling*3; + if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666) + scs_scaling = scs_scaling>>2; + uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); + + uint16_t ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index); + + get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, + frame, + mac->mib, + nr_slots_per_frame[scs_ssb], + ssb_subcarrier_offset, + ssb_start_symbol, + scs_ssb, + frequency_range, + ssb_index, + absolute_diff/(12*scs_scaling)-10); + + + 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; + } - 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 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"); +int8_t nr_ue_decode_BCCH_DL_SCH(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(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); return 0; } @@ -449,8 +476,9 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits); - 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)); + if (nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15)) + return -1; + return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci->rnti, dci->dci_format)); } int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint8_t dci_format){ @@ -583,7 +611,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr } } - break; } @@ -814,7 +841,17 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr 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; + + // FIXME: fix number of additional dmrs + if(pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition == NULL) + pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition=calloc(1,sizeof(*pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition)); + 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; + + dlsch_config_pdu_1_1->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_1->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_1->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + /* IDENTIFIER_DCI_FORMATS */ /* CARRIER_IND */ /* BANDWIDTH_PART_IND */ @@ -1010,6 +1047,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr &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; + LOG_D(MAC, "DL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", dlsch_config_pdu_1_1->PTRSTimeDensity, dlsch_config_pdu_1_1->PTRSFreqDensity); } } @@ -1119,11 +1157,11 @@ int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){ } 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) { + 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 = get_rnti_type(mac, rnti); @@ -1137,32 +1175,6 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, int pos=0; int fsize=0; - if (rnti_type == NR_RNTI_C) { - // First find out the DCI format from the first bit (UE performed blind decoding) - pos++; - dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; -#ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu); -#endif - - if (dci_format == NR_UL_DCI_FORMAT_0_0 || dci_format == NR_DL_DCI_FORMAT_1_0) { - if (dci_pdu_rel15->format_indicator == 0) - dci_format = NR_UL_DCI_FORMAT_0_0; - else - dci_format = NR_DL_DCI_FORMAT_1_0; - } - else if (dci_format == NR_UL_DCI_FORMAT_0_1 || dci_format == NR_DL_DCI_FORMAT_1_1) { - // In case the sizes of formats 0_1 and 1_1 happen to be the same - if (dci_pdu_rel15->format_indicator == 0) - dci_format = NR_UL_DCI_FORMAT_0_1; - else - dci_format = NR_DL_DCI_FORMAT_1_1; - } - } -#ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC, "DCI format is %d\n", dci_format); -#endif - switch(dci_format) { case NR_DL_DCI_FORMAT_1_0: @@ -1203,7 +1215,15 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, break; case NR_RNTI_C: - + + //Identifier for DCI formats + pos++; + dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + if (dci_pdu_rel15->format_indicator == 0) + return 1; // discard dci, format indicator not corresponding to dci_format +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu); +#endif // Freq domain assignment (275rb >> fsize = 16) fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); pos+=fsize; @@ -1385,6 +1405,8 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, // indicating a DL DCI format 1bit pos++; dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + if (dci_pdu_rel15->format_indicator == 0) + return 1; // discard dci, format indicator not corresponding to dci_format // Freq domain assignment 0-16 bit fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); pos+=fsize; @@ -1423,6 +1445,11 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, switch(rnti_type) { case NR_RNTI_C: + //Identifier for DCI formats + pos++; + dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + if (dci_pdu_rel15->format_indicator == 1) + return 1; // discard dci, format indicator not corresponding to dci_format fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); pos+=fsize; dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<format_indicator = (*dci_pdu>>(dci_size-pos))&1; + if (dci_pdu_rel15->format_indicator == 0) + return 1; // discard dci, format indicator not corresponding to dci_format // Carrier indicator pos+=dci_pdu_rel15->carrier_indicator.nbits; dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<carrier_indicator.nbits)-1); @@ -1583,6 +1615,11 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, switch(rnti_type) { case NR_RNTI_C: + //Identifier for DCI formats + pos++; + dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1; + if (dci_pdu_rel15->format_indicator == 1) + return 1; // discard dci, format indicator not corresponding to dci_format // Carrier indicator pos+=dci_pdu_rel15->carrier_indicator.nbits; dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<carrier_indicator.nbits)-1); @@ -1691,7 +1728,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, break; } - return dci_format; + return 0; } /////////////////////////////////// @@ -1736,7 +1773,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, 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; + int32_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; @@ -1747,7 +1784,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, return; } - 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); + LOG_D(MAC, "In %s [%d.%d]: processing PDU %d (with length %d) of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, pdu_len, dl_info->rx_ind->number_pdus); while (!done && pdu_len > 0){ mac_ce_len = 0x0000; @@ -1951,7 +1988,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, 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); + LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", module_idP, frameP, slot, pdu_len); } } @@ -2230,7 +2267,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t // TA command ul_time_alignment->apply_ta = 1; - ul_time_alignment->ta_command = rar->TA2 + (rar->TA1 << 5); + ul_time_alignment->ta_command = 31 + rar->TA2 + (rar->TA1 << 5); #ifdef DEBUG_RAR // CSI diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index d6e1cba6df..844ee95d32 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -109,7 +109,11 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { } k2 = *pusch_TimeDomainAllocationList->list.array[time_domain_ind]->k2; } - + + AssertFatal(k2 >= DURATION_RX_TO_TX, + "Slot offset K2 (%ld) cannot be less than DURATION_RX_TO_TX (%d)\n", + k2,DURATION_RX_TO_TX); + LOG_D(MAC, "get_k2(): k2 is %ld\n", k2); return k2; } @@ -118,13 +122,14 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { * 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) { +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) { + if (is_nr_UL_slot(mac->scc, slot, mac->frame_type) == 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 @@ -560,20 +565,11 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, } 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; + bool valid_ptrs_setup = 0; 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); @@ -689,12 +685,6 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, 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) @@ -708,12 +698,20 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, } /* 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 + if (mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS != NULL) { + if (pusch_config_pdu->transform_precoding == transform_precoder_disabled) { + nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; + pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; + valid_ptrs_setup = set_ul_ptrs_values(mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->phaseTrackingRS->choice.setup, + pusch_config_pdu->rb_size, pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table, + &pusch_config_pdu->pusch_ptrs.ptrs_freq_density,&pusch_config_pdu->pusch_ptrs.ptrs_time_density, + &pusch_config_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset,&pusch_config_pdu->pusch_ptrs.num_ptrs_ports, + &pusch_config_pdu->pusch_ptrs.ul_ptrs_power, pusch_config_pdu->nr_of_symbols); + if(valid_ptrs_setup==true) { + pusch_config_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; + } + LOG_D(MAC, "UL PTRS values: PTRS time den: %d, PTRS freq den: %d\n", pusch_config_pdu->pusch_ptrs.ptrs_time_density, pusch_config_pdu->pusch_ptrs.ptrs_freq_density); + } } } @@ -889,34 +887,40 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in 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); - } + if (ra->ra_state == WAIT_RAR){ + memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes); + LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n"); + for (int k = 0; k < TBS_bytes; k++) { + LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]); + } + } else { + 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); + 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; + //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]); + for (int i = 1; i < TBS_bytes; i++) { + ulsch_input_buffer[i] = (unsigned char) rand(); + } } } @@ -997,6 +1001,10 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, break; } + AssertFatal((k2+delta) >= DURATION_RX_TO_TX, + "Slot offset (%d) for Msg3 cannot be less than DURATION_RX_TO_TX (%d)\n", + k2+delta,DURATION_RX_TO_TX); + *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; @@ -1662,7 +1670,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s 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)) { + if (is_nr_UL_slot(scc, slotP, mac->frame_type)) { // WIP Need to get the proper selected ssb_idx // Initial beam selection functionality is not available yet @@ -1683,13 +1691,11 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s 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; + + fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH); + 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); @@ -1767,11 +1773,10 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s AssertFatal(1 == 0, "Invalid PRACH format"); } } // if format1 + 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); } // 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 } diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 6aa906b82b..d0a8037307 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -45,7 +45,7 @@ #include "NR_MIB.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" - +#include "../../../../nfapi/oai_integration/vendor_ext.h" /* Softmodem params */ #include "executables/softmodem-common.h" @@ -54,7 +54,7 @@ extern RAN_CONTEXT_t RC; extern void mac_top_init_gNB(void); extern uint8_t nfapi_mode; -void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { +void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0]; RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc; @@ -127,8 +127,7 @@ 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; - get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type); + lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type; // Cell configuration @@ -241,6 +240,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell; cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG; cfg->num_tlv++; + cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset; + cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG; + cfg->num_tlv++; switch (scc->ssb_PositionsInBurst->present) { case 1 : @@ -264,18 +266,33 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm } cfg->ssb_table.ssb_mask_list[0].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG; - cfg->num_tlv++; + cfg->ssb_table.ssb_mask_list[1].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG; + cfg->num_tlv+=2; cfg->carrier_config.num_tx_ant.value = pdsch_AntennaPorts; AssertFatal(pdsch_AntennaPorts > 0 && pdsch_AntennaPorts < 13, "pdsch_AntennaPorts in 1...12\n"); cfg->carrier_config.num_tx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_TX_ANT_TAG; + int num_ssb=0; for (int i=0;i<32;i++) { - num_ssb += (cfg->ssb_table.ssb_mask_list[0].ssb_mask.value>>i)&1; - num_ssb += (cfg->ssb_table.ssb_mask_list[1].ssb_mask.value>>i)&1; + cfg->ssb_table.ssb_beam_id_list[i].beam_id.tl.tag = NFAPI_NR_CONFIG_BEAM_ID_TAG; + if ((cfg->ssb_table.ssb_mask_list[0].ssb_mask.value>>(31-i))&1) { + cfg->ssb_table.ssb_beam_id_list[i].beam_id.value = num_ssb; + num_ssb++; + } + cfg->num_tlv++; + } + for (int i=0;i<32;i++) { + cfg->ssb_table.ssb_beam_id_list[32+i].beam_id.tl.tag = NFAPI_NR_CONFIG_BEAM_ID_TAG; + if ((cfg->ssb_table.ssb_mask_list[1].ssb_mask.value>>(31-i))&1) { + cfg->ssb_table.ssb_beam_id_list[32+i].beam_id.value = num_ssb; + num_ssb++; + } + cfg->num_tlv++; } - cfg->carrier_config.num_rx_ant.value = cfg->carrier_config.num_tx_ant.value; + cfg->carrier_config.num_rx_ant.value = pusch_AntennaPorts; + AssertFatal(pusch_AntennaPorts > 0 && pusch_AntennaPorts < 13, "pusch_AntennaPorts in 1...12\n"); cfg->carrier_config.num_rx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_RX_ANT_TAG; LOG_I(MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value); AssertFatal(cfg->carrier_config.num_tx_ant.value > 0,"carrier_config.num_tx_ant.value %d !\n",cfg->carrier_config.num_tx_ant.value ); @@ -295,27 +312,28 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm } 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, - scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols, - scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots, - scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols); + int periods_per_frame = set_tdd_config_nr(cfg, + scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots, + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols, + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots, + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols); - if (return_tdd != 0) + if (periods_per_frame < 0) LOG_E(MAC,"TDD configuration can not be done\n"); - else + else { LOG_I(MAC,"TDD has been properly configurated\n"); + RC.nrmac[Mod_idP]->tdd_beam_association = (int16_t *)malloc16(periods_per_frame*sizeof(int16_t)); + } } } - - extern uint16_t sl_ahead; -int rrc_mac_config_req_gNB(module_id_t Mod_idP, - int ssb_SubcarrierOffset, +int rrc_mac_config_req_gNB(module_id_t Mod_idP, + int ssb_SubcarrierOffset, int pdsch_AntennaPorts, + int pusch_AntennaPorts, int pusch_tgt_snrx10, int pucch_tgt_snrx10, NR_ServingCellConfigCommon_t *scc, @@ -361,19 +379,22 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n"); config_common(Mod_idP, - pdsch_AntennaPorts, + ssb_SubcarrierOffset, + pdsch_AntennaPorts, + pusch_AntennaPorts, scc); LOG_E(MAC, "%s() %s:%d RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req); // if in nFAPI mode - if ( (nfapi_mode == 1 || nfapi_mode == 2) && (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) ){ + if ( (NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) && (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) ){ while(RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) { - // DJP AssertFatal(RC.nrmac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); - usleep(100 * 1000); - printf("Waiting for PHY_config_req\n"); + // DJP AssertFatal(RC.nrmac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); + usleep(100 * 1000); + printf("Waiting for PHY_config_req\n"); } } - + + RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = ssb_SubcarrierOffset; RC.nrmac[Mod_idP]->pusch_target_snrx10 = pusch_tgt_snrx10; RC.nrmac[Mod_idP]->pucch_target_snrx10 = pucch_tgt_snrx10; NR_PHY_Config_t phycfg; @@ -381,10 +402,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, phycfg.CC_id = 0; phycfg.cfg = &RC.nrmac[Mod_idP]->config[0]; - phycfg.cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset; - phycfg.cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG; - phycfg.cfg->num_tlv++; - if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg); find_SSB_and_RO_available(Mod_idP); @@ -400,21 +417,37 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, 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 */ const int CC_id = 0; - NR_RA_t *ra = &RC.nrmac[Mod_idP]->common_channels[CC_id].ra[0]; - ra->state = RA_IDLE; + NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[CC_id]; + uint8_t ra_index = 0; + /* checking for free RA process */ + for(; ra_index < NR_NB_RA_PROC_MAX; ra_index++) { + if((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra)) break; + } + if (ra_index == NR_NB_RA_PROC_MAX) { + LOG_E(MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti); + return -1; + } + NR_RA_t *ra = &cc->ra[ra_index]; ra->secondaryCellGroup = secondaryCellGroup; 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; + 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; + for(int i=0; inum_active_ssb; i++) { + for(int j=0; jssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) { + // one dedicated preamble for each beam + ra->preambles.preamble_list[i] = + cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex; + break; + } + } + } } } LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index d5dbbe5ddf..584648c67f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -52,6 +52,7 @@ #include "intertask_interface.h" #include "executables/softmodem-common.h" +#include "nfapi/oai_integration/vendor_ext.h" uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; @@ -65,11 +66,15 @@ void dump_mac_stats(gNB_MAC_INST *gNB) 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", + NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; + const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; + LOG_I(MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n", UE_id, stats->dlsch_rounds[0], stats->dlsch_rounds[1], - stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors); + stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors, + avg_rsrp, stats->num_rsrp_meas); + stats->num_rsrp_meas = 0; + stats->cumul_rsrp = 0 ; 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, @@ -104,7 +109,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, gNB->pdu_index[CC_idP] = 0; - if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF + if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) { // monolithic or PNF DL_req[CC_idP].SFN = frameP; DL_req[CC_idP].Slot = slotP; @@ -296,6 +301,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) { + if (slot>64) return false; //quickfix for FR2 where there are more than 64 slots (bitmap to be removed) return (bitmap >> slot) & 0x01; } @@ -352,6 +358,12 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, AssertFatal(1==0,"Undefined tdd period %ld\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); } + if (slot==0 && (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]>=257)) { + // re-initialization of tdd_beam_association at beginning of frame (only for FR2) + for (int i=0; itdd_beam_association[i] = -1; + } + 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); @@ -363,14 +375,22 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, /* send tick to RLC and RRC every ms */ if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) { void nr_rlc_tick(int frame, int subframe); + void nr_pdcp_tick(int frame, int subframe); nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing); + nr_pdcp_tick(frame, slot >> *scc->ssbSubcarrierSpacing); nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing); } #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); + + uint8_t prach_config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + uint64_t ulsch_in_slot_bitmap; + if (prach_config_index==4) //this is the PRACH config used in the Benetel RRU. TODO: make this generic for any PRACH config. + ulsch_in_slot_bitmap = BIT( 8) | BIT( 9); + else + 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 @@ -397,7 +417,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, // This schedules MIB - schedule_nr_mib(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]); + schedule_nr_mib(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing],nb_periods_per_frame); // This schedules SIB1 if ( get_softmodem_params()->sa == 1 ) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index b914e80d23..bc297225af 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -151,6 +151,38 @@ void find_SSB_and_RO_available(module_id_t module_idP) { uint8_t num_active_ssb = 0; uint8_t max_association_period = 1; + struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *ssb_perRACH_OccasionAndCB_PreamblesPerSSB = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB; + + switch (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present){ + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: + cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: + cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: + cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: + cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen; + break; + default: + AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present); + break; + } + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; else @@ -181,25 +213,28 @@ void find_SSB_and_RO_available(module_id_t module_idP) { } } - for(int i = 1; (1 << (i-1)) <= max_association_period;i++) { + cc->total_prach_occasions_per_config_period = total_RA_occasions; + for(int i=1; (1 << (i-1)) < max_association_period; i++) { + cc->max_association_period = (1 <<(i-1)); + total_RA_occasions = total_RA_occasions * cc->max_association_period; 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); + LOG_I(MAC, + "Total available RO %d, num of active SSB %d: unused RO = %d association_period %u N_RA_sfn %u total_prach_occasions_per_config_period %u\n", + cc->total_prach_occasions, + cc->num_active_ssb, + unused_RA_occasion, + cc->max_association_period, + N_RA_sfn, + cc->total_prach_occasions_per_config_period); } void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) @@ -210,7 +245,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP 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)) { + if (is_nr_UL_slot(scc, slotP, cc->frame_type)) { + 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 = 0,N_RA_slot; uint16_t RA_sfn_index = -1; @@ -349,7 +385,9 @@ 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,uint8_t index,uint8_t num_active_ssb){ + uint16_t monitoring_offset,uint8_t beam_index, + uint8_t num_active_ssb, + int16_t *tdd_beam_association){ // preferentially we schedule the msg2 in the mixed slot or in the last dl slot // if they are allowed by search space configuration @@ -366,18 +404,6 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, if ((scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) || (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0)) tdd_period_slot++; - // computing start of next period - uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu]; - *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot - *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1); - - // 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; @@ -412,6 +438,31 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, 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); + // computing start of next period + + int FR = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257 ? nr_FR2 : nr_FR1; + + uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu]; + *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot + *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1); + + // 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); + } + if (FR==nr_FR2) { + int num_tdd_period = *msg2_slot/tdd_period_slot; + while((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=beam_index)) { + *msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu]; + *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1); + num_tdd_period = *msg2_slot/tdd_period_slot; + } + if(tdd_beam_association[num_tdd_period] == -1) + tdd_beam_association[num_tdd_period] = beam_index; + } + // 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>frame_limit)) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) { @@ -439,139 +490,167 @@ void nr_initiate_ra_proc(module_id_t module_idP, gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_RA_t *ra = &cc->ra[0]; - uint16_t ra_rnti; + uint8_t total_RApreambles = 64; + uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + int pr_found; - // 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; - for (int i = 0; i < ra->preambles.num_preambles; i++) { - if (preamble_index == ra->preambles.preamble_list[i]) { - pr_found=1; - break; - } + if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) + total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; + + if(num_ssb_per_RO > 3) { /*num of ssb per RO >= 1*/ + num_ssb_per_RO -= 3; + total_RApreambles = total_RApreambles/num_ssb_per_RO ; } - 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]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); - - LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index); - - if (ra->state == RA_IDLE) { - - 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; - ra->timing_offset = timing_offset; - ra->preamble_slot = slotP; - - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - AssertFatal(commonSearchSpaceList->list.count>0, - "common SearchSpace list has 0 elements\n"); - // Common searchspace list - for (int i=0;ilist.count;i++) { - ss=commonSearchSpaceList->list.array[i]; - if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace) - ra->ra_ss=ss; - } - - // retrieving ra pdcch monitoring period and offset - find_monitoring_periodicity_offset_common(ra->ra_ss, - &monitoring_slot_period, - &monitoring_offset); - - nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset,beam_index,cc->num_active_ssb); - - ra->Msg2_frame = msg2_frame; - ra->Msg2_slot = msg2_slot; - - 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++; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; + pr_found = 0; + if (ra->state == RA_IDLE) { + for(int j = 0; j < ra->preambles.num_preambles; j++) { + //check if the preamble received correspond to one of the listed or configured preambles + if (preamble_index == ra->preambles.preamble_list[j]) { + pr_found=1; + break; + } } - 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(); + if (pr_found == 0) { + continue; } + + 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); + + // 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]; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); + + LOG_I(MAC, + "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", + module_idP, + CC_id, + frameP, + slotP, + preamble_index); + + uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol); + + // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries + if (ra->cfra) { + // if the preamble received correspond to one of the listed + if (!(preamble_index == ra->preambles.preamble_list[beam_index])) { + 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); + continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc + } + } + int loop = 0; + LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); + ra->state = Msg2; + ra->timing_offset = timing_offset; + ra->preamble_slot = slotP; + + struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); + // Common searchspace list + for (int i = 0; i < commonSearchSpaceList->list.count; i++) { + ss = commonSearchSpaceList->list.array[i]; + if (ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace) + ra->ra_ss = ss; + } + + // retrieving ra pdcch monitoring period and offset + find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); + + nr_schedule_msg2(frameP, + slotP, + &msg2_frame, + &msg2_slot, + scc, + monitoring_slot_period, + monitoring_offset, + beam_index, + cc->num_active_ssb, + nr_mac->tdd_beam_association); + + ra->Msg2_frame = msg2_frame; + ra->Msg2_slot = msg2_slot; + + 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(); + } + } + 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 SSB " + "index %u\n", + module_idP, + CC_id, + frameP, + ra->Msg2_frame, + ra->Msg2_slot, + ra->RA_rnti, + cc->ssb_index[beam_index]); + + return; } - 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 SSB index %u\n", - module_idP, - CC_id, - frameP, - ra->Msg2_frame, - ra->Msg2_slot, - ra->RA_rnti, - cc->ssb_index[beam_index]); - - return; } LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } -void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ - - //uint8_t i = 0; - int CC_id = 0; +void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) +{ gNB_MAC_INST *mac = RC.nrmac[module_idP]; - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; start_meas(&mac->schedule_ra); - -// 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); - break; - case WAIT_Msg4_ACK: - //check_Msg4_retransmission(module_idP, CC_id, frameP, slotP); - break; - default: - break; + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + NR_RA_t *ra = &cc->ra[i]; + LOG_D(MAC, "RA[state:%d]\n", ra->state); + switch (ra->state) { + case Msg2: + nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra); + break; + case Msg4: + // generate_Msg4(module_idP, CC_id, frameP, slotP); + break; + case WAIT_Msg4_ACK: + // check_Msg4_retransmission(module_idP, CC_id, frameP, slotP); + break; + default: + break; + } + } } -// } -// } stop_meas(&mac->schedule_ra); } @@ -581,10 +660,12 @@ void nr_get_Msg3alloc(module_id_t module_id, NR_BWP_Uplink_t *ubwp, sub_frame_t current_slot, frame_t current_frame, - NR_RA_t *ra) { + NR_RA_t *ra, + int16_t *tdd_beam_association) { // msg3 is schedulend in mixed slot in the following TDD period - // for now we consider a TBS of 18 bytes + + uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing; int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot; @@ -610,34 +691,46 @@ void nr_get_Msg3alloc(module_id_t module_id, else ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]); + // beam association for FR2 + if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) { + uint8_t tdd_period_slot = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + if ((scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) || (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0)) + tdd_period_slot++; + int num_tdd_period = ra->Msg3_slot/tdd_period_slot; + if((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=ra->beam_id)) + AssertFatal(1==0,"Cannot schedule MSG3\n"); + else + tdd_beam_association[num_tdd_period] = ra->beam_id; + } + 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 */ + + /* search msg3_nb_rb free RBs */ int rbSize = 0; int rbStart = 0; - while (rbSize < 18) { + while (rbSize < msg3_nb_rb) { 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"); + AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n"); while (rbStart + rbSize < bwpSize && !vrb_map_UL[rbStart + rbSize] - && rbSize < 18) + && rbSize < msg3_nb_rb) rbSize++; } - ra->msg3_nb_rb = 18; + ra->msg3_nb_rb = msg3_nb_rb; ra->msg3_first_rb = rbStart; } -void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){ - +void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu) +{ gNB_MAC_INST *mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_RA_t *ra = &cc->ra[0]; if (ra->state == RA_IDLE) { LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); @@ -752,27 +845,25 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t pusch_pdu->nrOfLayers = 1)>>3; // calling function to fill rar message - nr_fill_rar(module_idP, ra, cc->RAR_pdu.payload, pusch_pdu); - + nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu); } -// WIP -// todo: -// - fix me -// - get msg3 alloc (see nr_process_rar) -void nr_generate_Msg2(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP) +void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) { - 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[CC_id]; - NR_RA_t *ra = &cc->ra[CC_id]; NR_SearchSpace_t *ss = ra->ra_ss; + // This code from this point on will not work on initialBWP or CORESET0 + AssertFatal(ra->bwp_id > 0, "cannot work on initialBWP for now\n"); + + AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->crnti); + AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + uint16_t RA_rnti = ra->RA_rnti; long locationAndBandwidth; @@ -780,7 +871,7 @@ void nr_generate_Msg2(module_id_t module_idP, // get the BW of the PDCCH for PDCCH size and RAR PDSCH size NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - int dci10_bw; + int dci10_bw = 0; if (ra->coreset0_configured == 1) { AssertFatal(1==0,"This is a standalone condition\n"); @@ -792,8 +883,24 @@ void nr_generate_Msg2(module_id_t module_idP, if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { + uint16_t *vrb_map = cc[CC_id].vrb_map; + int rbStart = 0, rbSize = 6; + for (int i = 0; (i < rbSize) && (rbStart <= (dci10_bw - rbSize)); i++) { + if (vrb_map[rbStart + i]) { + rbStart += i; + i = 0; + } + } + if (rbStart > (dci10_bw - rbSize)) { + LOG_E(MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti); + return; + } + nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; - // Checking if the DCI allocation is feasible in current subframe + // Checking if the DCI allocation is feasible in current subframe: we might + // need to need up to two (PDCCH + PDSCH) messages, so check that we can + // always allocate both (this might be an overestimation, since the PDCCH + // message might already exist) 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; @@ -816,8 +923,6 @@ void nr_generate_Msg2(module_id_t module_idP, 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 */ @@ -844,14 +949,6 @@ void nr_generate_Msg2(module_id_t module_idP, LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); - // This code from this point on will not work on initialBWP or CORESET0 - AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n"); - - AssertFatal(ra->secondaryCellGroup, - "no secondaryCellGroup for RNTI %04x\n", - ra->crnti); - AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw); @@ -892,14 +989,14 @@ void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; - pdsch_pdu_rel15->dmrsConfigType = 0; + pdsch_pdu_rel15->dmrsConfigType = 0;//Reconfigure Msg2 to use pdsch_dmrs_type1 pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2; pdsch_pdu_rel15->dmrsPorts = 1; pdsch_pdu_rel15->resourceAlloc = 1; - pdsch_pdu_rel15->rbStart = 0; - pdsch_pdu_rel15->rbSize = 6; + pdsch_pdu_rel15->rbStart = rbStart; + pdsch_pdu_rel15->rbSize = rbSize; pdsch_pdu_rel15->VRBtoPRBMapping = 0; // non interleaved for (int i=0; ibwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) { @@ -918,6 +1015,12 @@ 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); + pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=1; + pdsch_pdu_rel15->precodingAndBeamforming.prg_size=275; + pdsch_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces=1; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + pdsch_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = ra->beam_id; + /* 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++; @@ -934,7 +1037,7 @@ void nr_generate_Msg2(module_id_t module_idP, 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); + pdsch_pdu_rel15->rbStart,dci10_bw); 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]; @@ -974,17 +1077,8 @@ void nr_generate_Msg2(module_id_t module_idP, dci10_bw, ra->bwp_id); - // Program UL processing for Msg3 - 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_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_payload.tb_scaling); - // DL TX request + nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0]; tx_req->PDU_index = pduindex; tx_req->num_TLV = 1; @@ -992,16 +1086,24 @@ void nr_generate_Msg2(module_id_t module_idP, nr_mac->TX_req[CC_id].SFN = frameP; nr_mac->TX_req[CC_id].Number_of_PDUs++; nr_mac->TX_req[CC_id].Slot = slotP; - memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length); + + // Program UL processing for Msg3 + nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra, nr_mac->tdd_beam_association); + LOG_I(MAC, "Frame %d, Slot %d: Setting Msg3 reception for Frame %d Slot %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); + nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]); + ra->state = WAIT_Msg3; + LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Slot %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_payload.tb_scaling); 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)); + T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length)); /* mark the corresponding RBs as used */ - 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; + for (int rb = 0; rb < rbSize; rb++) + vrb_map[rb + rbStart] = 1; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 1de46aaea4..444eabb789 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -53,26 +53,12 @@ #include "executables/softmodem-common.h" 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; - - nfapi_nr_dl_tti_request_t *dl_tti_request; - nfapi_nr_dl_tti_request_body_t *dl_req; - nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu; +uint16_t get_ssboffset_pointa(NR_ServingCellConfigCommon_t *scc,const long band) { - int mib_sdu_length; - int CC_id; - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - 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) { + int ratio; + switch (*scc->ssbSubcarrierSpacing) { case NR_SubcarrierSpacing_kHz15: AssertFatal(band <= 79, "Band %ld is not possible for SSB with 15 kHz SCS\n", @@ -105,116 +91,199 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, break; default: AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n", - *cc->ServingCellConfigCommon->ssbSubcarrierSpacing); - } + *scc->ssbSubcarrierSpacing); + } - // scheduling MIB every 8 frames, PHY repeats it in between + const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; + + return (ssb_offset0/(ratio*12) - 10); // absoluteFrequencySSB is the center of SSB + +} + + +void schedule_ssb(frame_t frame, sub_frame_t slot, + NR_ServingCellConfigCommon_t *scc, + nfapi_nr_dl_tti_request_body_t *dl_req, + int i_ssb, uint8_t scoffset, uint16_t offset_pointa, uint32_t payload) { + + uint8_t beam_index = 0; + nfapi_nr_dl_tti_request_pdu_t *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(scc->physCellId!=NULL,"ServingCellConfigCommon->physCellId is null\n"); + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i_ssb; + AssertFatal(scc->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n"); + AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n"); + AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n"); + AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n", + scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count); + AssertFatal(scc->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n"); + AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n"); + + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = scoffset; //kSSB + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = offset_pointa; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = payload; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs=1; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size=275; //1 PRG of max size for analogue beamforming + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces=1; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].pm_idx = 0; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index; + dl_req->nPDUs++; + + LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n",i_ssb,frame,slot); + +} + +void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, uint8_t slots_per_frame, int nb_periods_per_frame){ + + gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc; + nfapi_nr_dl_tti_request_t *dl_tti_request; + nfapi_nr_dl_tti_request_body_t *dl_req; + NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib; + uint8_t num_tdd_period,num_ssb; + int mib_sdu_length; + int CC_id; + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + cc = &gNB->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + dl_tti_request = &gNB->DL_req[CC_id]; + dl_req = &dl_tti_request->dl_tti_request_body; + + // get MIB every 8 frames if((slotP == 0) && (frameP & 7) == 0) { - dl_tti_request = &gNB->DL_req[CC_id]; - dl_req = &dl_tti_request->dl_tti_request_body; mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]); - LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, 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_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++; - } - - // 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); - } - 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); - + LOG_D(MAC, + "[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n", + module_idP, + frameP, + CC_id, + mib_sdu_length); } - // 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); + int8_t ssb_period = *scc->ssb_periodicityServingCell; + uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated + + if (ssb_period > 1) // 0 is every half frame + ssb_frame_periodicity = 1 << (ssb_period -1); + + if (!(frameP%ssb_frame_periodicity) && + ((slotP<(slots_per_frame>>1)) || (ssb_period == 0))) { + // schedule SSB only for given frames according to SSB periodicity + // and in first half frame unless periodicity of 5ms + int rel_slot; + if (ssb_period == 0) // scheduling every half frame + rel_slot = slotP%(slots_per_frame>>1); + else + rel_slot = slotP; + + NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing; + const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + uint16_t offset_pointa = get_ssboffset_pointa(scc,band); + uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset; + + const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap; + const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap; + const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap; + + uint16_t ssb_start_symbol; + + switch (scc->ssb_PositionsInBurst->present) { + case 1: + // short bitmap (<3GHz) max 4 SSBs + for (int i_ssb=0; i_ssb<4; i_ssb++) { + if ((shortBitmap->buf[0]>>(7-i_ssb))&0x01) { + ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb); + // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters + if ((ssb_start_symbol/14) == rel_slot){ + schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1)); + fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id); + if (get_softmodem_params()->sa == 1) { + get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], + frameP, + mib, + slots_per_frame, + ssbSubcarrierOffset, + ssb_start_symbol, + scs, + FR1, + i_ssb, + offset_pointa); + gNB->type0_PDCCH_CSS_config[i_ssb].active = true; + } + } + } + } + break; + case 2: + // medium bitmap (<6GHz) max 8 SSBs + for (int i_ssb=0; i_ssb<8; i_ssb++) { + if ((mediumBitmap->buf[0]>>(7-i_ssb))&0x01) { + ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb); + // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters + if ((ssb_start_symbol/14) == rel_slot){ + schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1)); + fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id); + if (get_softmodem_params()->sa == 1) { + get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], + frameP, + mib, + slots_per_frame, + ssbSubcarrierOffset, + ssb_start_symbol, + scs, + FR1, + i_ssb, + offset_pointa); + gNB->type0_PDCCH_CSS_config[i_ssb].active = true; + } + } + } + } + break; + case 3: + // long bitmap FR2 max 64 SSBs + num_ssb = 0; + for (int i_ssb=0; i_ssb<63; i_ssb++) { + if ((longBitmap->buf[i_ssb/8]>>(7-i_ssb))&0x01) { + ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb); + // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters + if ((ssb_start_symbol/14) == rel_slot){ + schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1)); + fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id); + num_tdd_period = rel_slot/(slots_per_frame/nb_periods_per_frame); + gNB->tdd_beam_association[num_tdd_period]=i_ssb; + num_ssb++; + AssertFatal(num_ssb<2,"beamforming currently not supported for more than one SSB per slot\n"); + if (get_softmodem_params()->sa == 1) { + get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], + frameP, + mib, + slots_per_frame, + ssbSubcarrierOffset, + ssb_start_symbol, + scs, + FR2, + i_ssb, + offset_pointa); + gNB->type0_PDCCH_CSS_config[i_ssb].active = true; + } + } + } + } + break; + default: + AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n", + scc->ssb_PositionsInBurst->present); + } } } } @@ -224,17 +293,26 @@ void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframe //---------------------------------------- } -void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id) { +void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id) { + + AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing != + NR_SubcarrierSpacing_kHz240, + "240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n"); + uint16_t *vrb_map = cc[CC_id].vrb_map; + for (int rb = 0; rb < 20; rb++) - vrb_map[rbStart + rb] = 1; + vrb_map[rbStart + rb] = 15<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); @@ -266,16 +343,13 @@ void schedule_control_sib1(module_id_t module_id, gNB_mac->sched_ctrlCommon->coreset, gNB_mac->sched_ctrlCommon->aggregation_level, 0, - 0, + candidate_idx, nr_of_candidates); - if (gNB_mac->sched_ctrlCommon->cce_index < 0) { - LOG_E(MAC, "%s(): could not find CCE for coreset0\n", __func__); - return; - } + AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n"); - const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs; - int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb; + const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs; + int rbStart = 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; @@ -301,9 +375,7 @@ void schedule_control_sib1(module_id_t module_id, 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) ); + } while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes); gNB_mac->sched_ctrlCommon->rbSize = rbSize; gNB_mac->sched_ctrlCommon->rbStart = 0; @@ -322,6 +394,7 @@ void schedule_control_sib1(module_id_t module_id, void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, nfapi_nr_dl_tti_request_body_t *dl_req, + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, uint32_t TBS, int StartSymbolIndex, int NrOfSymbols) { @@ -344,6 +417,10 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, scc, bwp); + // TODO: This assignment should be done in function nr_configure_pdcch() + pdcch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config->num_rbs; + pdcch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config->cset_start_rb; + 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; @@ -357,8 +434,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, 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->BWPSize = type0_PDCCH_CSS_config->num_rbs; + pdsch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb; pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; if (bwp->bwp_Common->genericParameters.cyclicPrefix) { @@ -415,7 +492,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, // 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); + pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, 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; @@ -467,54 +544,83 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) int time_domain_allocation = 0; uint8_t mcsTableIdx = 0; uint8_t mcs = 6; + uint8_t candidate_idx = 0; gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; + NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon; - 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) ) { + int L_max; + switch (scc->ssb_PositionsInBurst->present) { + case 1: + L_max = 4; + break; + case 2: + L_max = 8; + break; + case 3: + L_max = 64; + break; + default: + AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n", + scc->ssb_PositionsInBurst->present); + } - LOG_D(MAC,"> SIB1 transmission\n"); + for (int i=0; itype0_PDCCH_CSS_config[i]; - // Configure sched_ctrlCommon for SIB1 - schedule_control_sib1(module_idP, CC_id, time_domain_allocation, mcsTableIdx, mcs, sib1_sdu_length); + if((frameP%2 == type0_PDCCH_CSS_config->sfn_c) && + (slotP == type0_PDCCH_CSS_config->n_0) && + (type0_PDCCH_CSS_config->num_rbs > 0) && + (type0_PDCCH_CSS_config->active == true)) { - // Calculate number of symbols - int startSymbolIndex, nrOfSymbols; - 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; - SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); + LOG_D(MAC,"> SIB1 transmission\n"); - // 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); + // 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->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; + // Configure sched_ctrlCommon for SIB1 + schedule_control_sib1(module_idP, CC_id, type0_PDCCH_CSS_config, time_domain_allocation, mcsTableIdx, mcs, candidate_idx, sib1_sdu_length); - 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); + // Calculate number of symbols + int startSymbolIndex, nrOfSymbols; + 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; + SLIV2SL(startSymbolAndLength, &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]; + // 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); - // 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); + 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; - 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; + 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, type0_PDCCH_CSS_config, 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; + + type0_PDCCH_CSS_config->active = false; + } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 4d491b2843..30a89cce77 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1045,7 +1045,7 @@ void nr_schedule_ue_spec(module_id_t module_id, size += 3; } } - else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) { + else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra || get_softmodem_params()->sa) { /* 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; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 8dbe8728f3..6487f391b9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -103,7 +103,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, 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]; + dl_tti_pdsch_pdu = &nr_mac->DL_req[CC_id].dl_tti_request_body.dl_tti_pdu_list[nr_mac->DL_req[CC_id].dl_tti_request_body.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)); @@ -238,14 +238,16 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, pdsch_pdu_rel15->mcsIndex[0]); */ - dl_req->nPDUs+=2; + nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+=2; TX_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; TX_req->PDU_length = 6; TX_req->PDU_index = nr_mac->pdu_index[CC_id]++; TX_req->num_TLV = 1; TX_req->TLVs[0].length = 8; - memcpy((void*)&TX_req->TLVs[0].value.direct[0],(void*)&cc[CC_id].RAR_pdu.payload[0],TX_req->TLVs[0].length); + // why do we copy from RAR_pdu here? Shouldn't we fill some more or less + // meaningful data, e.g., padding + random data? + //memcpy((void *)&TX_req->TLVs[0].value.direct[0], (void *)&cc[CC_id].RAR_pdu[0].payload[0], TX_req->TLVs[0].length); nr_mac->TX_req[CC_id].Number_of_PDUs++; nr_mac->TX_req[CC_id].SFN=frameP; nr_mac->TX_req[CC_id].Slot=slotP; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 20da8fa30a..94524795f3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -646,6 +646,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, int res_found = 0; pucch_pdu->bit_len_harq = O_ack; + pucch_pdu->bit_len_csi_part1 = O_csi; uint16_t O_uci = O_csi + O_ack; @@ -698,6 +699,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, n_set = pucch_Config->resourceSetToAddModList->list.count; AssertFatal(n_set>0,"PUCCH resourceSetToAddModList is empty\n"); + LOG_D(MAC, "UCI n_set= %d\n", n_set); + N2 = 2; // procedure to select pucch resource id from resource sets according to // number of uci bits and pucch resource indicator pucch_resource @@ -1635,7 +1638,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secon 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); + compute_csi_bitlen (secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, mod_idP); 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; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index f0a20d8e6f..247a7e2c45 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -31,6 +31,7 @@ #include "NR_MAC_COMMON/nr_mac_extern.h" #include "NR_MAC_gNB/mac_proto.h" #include "common/ran_context.h" +#include "nfapi/oai_integration/vendor_ext.h" extern RAN_CONTEXT_t RC; @@ -79,6 +80,42 @@ void nr_fill_nfapi_pucch(module_id_t mod_id, pucch->sr_flag); } +#define MIN_RSRP_VALUE -141 +#define MAX_NUM_SSB 128 +#define MAX_SSB_SCHED 8 +#define L1_RSRP_HYSTERIS 10 //considering 10 dBm as hysterisis for avoiding frequent SSB Beam Switching. !Fixme provide exact value if any +//#define L1_DIFF_RSRP_STEP_SIZE 2 + +int ssb_index_sorted[MAX_NUM_SSB] = {0}; +int ssb_rsrp_sorted[MAX_NUM_SSB] = {0}; + +//Measured RSRP Values Table 10.1.16.1-1 from 36.133 +//Stored all the upper limits[Max RSRP Value of corresponding index] +//stored -1 for invalid values +int L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //0 - 9 + -1, -1, -1, -1, -1, -1, -140, -139, -138, -137, //10 - 19 + -136, -135, -134, -133, -132, -131, -130, -129, -128, -127, //20 - 29 + -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, //30 - 39 + -116, -115, -114, -113, -112, -111, -110, -109, -108, -107, //40 - 49 + -106, -105, -104, -103, -102, -101, -100, -99, -98, -97, //50 - 59 + -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, //60 - 69 + -86, -85, -84, -83, -82, -81, -80, -79, -78, -77, //70 - 79 + -76, -75, -74, -73, -72, -71, -70, -69, -68, -67, //80 - 89 + -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, //90 - 99 + -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, //100 - 109 + -46, -45, -44, -44, -1, -1, -1, -1, -1, -1, //110 - 119 + -1, -1, -1, -1, -1, -1, -1, -1//120 - 127 + }; + +//Differential RSRP values Table 10.1.6.1-2 from 36.133 +//Stored the upper limits[MAX RSRP Value] +int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = { + 0, -2, -4, -6, -8, -10, -12, -14, -16, -18, //0 - 9 + -20, -22, -24, -26, -28, -30 //10 - 15 +}; + + void nr_schedule_pucch(int Mod_idP, frame_t frameP, sub_frame_t slotP) { @@ -105,74 +142,293 @@ void nr_schedule_pucch(int Mod_idP, } +//! Calculating number of bits set +uint8_t number_of_bits_set (uint8_t buf,uint8_t * max_ri){ + uint8_t nb_of_bits_set = 0; + uint8_t mask = 0xff; + uint8_t index = 0; + + for (index=7; (buf & mask) && (index>=0) ; index--){ + if (buf & (1<>=1; + } + *max_ri = 8-index; + return nb_of_bits_set; +} + + //!TODO : same function can be written to handle csi_resources -void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t *UE_info, int UE_id) { +void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_info, int UE_id, module_id_t Mod_idP){ uint8_t csi_report_id = 0; uint8_t csi_resourceidx =0; uint8_t csi_ssb_idx =0; - - NR_CSI_MeasConfig_t *csi_MeasConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; NR_CSI_ResourceConfigId_t csi_ResourceConfigId; + for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ - csi_ResourceConfigId=csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->resourcesForChannelMeasurement; - UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->reportQuantity.present; + struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; + nr_csi_report_t *csi_report = &UE_info->csi_report_template[UE_id][csi_report_id]; + csi_ResourceConfigId=csi_reportconfig->resourcesForChannelMeasurement; + reportQuantity_type = csi_reportconfig->reportQuantity.present; + csi_report->reportQuantity_type = reportQuantity_type; for ( csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) { - if ( csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_ResourceConfigId != csi_ResourceConfigId) - continue; + struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; + if ( csi_resourceconfig->csi_ResourceConfigId != csi_ResourceConfigId) + continue; else { - //Finding the CSI_RS or SSB Resources - 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){ - struct NR_CSI_ResourceConfig__csi_RS_ResourceSetList__nzp_CSI_RS_SSB * nzp_CSI_RS_SSB = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB; + uint8_t nb_ssb_resources =0; + //Finding the CSI_RS or SSB Resources + if (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP == reportQuantity_type || + NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type) { - 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; + if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) { + if (NULL != csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS) + csi_report->CSI_report_bitlen.nb_ssbri_cri = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1; + else + /*! From Spec 38.331 + * nrofReportedRS + * The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE + * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report. + * When the field is absent the UE applies the value 1 + */ + csi_report->CSI_report_bitlen.nb_ssbri_cri= 1; + }else + csi_report->CSI_report_bitlen.nb_ssbri_cri= 2; + + if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) { + for ( csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) { + if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){ + + ///We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig + nb_ssb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.count; + csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.array; + csi_report->CSI_Index_list = NULL; + break; + } + } + } else /*if (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP == UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type)*/{ + for ( csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_ssb_idx++) { + if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_ssb_idx]->nzp_CSI_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { + + ///For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212 + nb_ssb_resources= csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_ssb_idx]->nzp_CSI_RS_Resources.list.count; + csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_ssb_idx]->nzp_CSI_RS_Resources.list.array; + csi_report->SSB_Index_list = NULL; + break; + } + } + } + + if (nb_ssb_resources) { + csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_ssb_resources)); + csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP + csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP + } else { + csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0; + csi_report->CSI_report_bitlen.rsrp_bitlen = 0; + csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0; + } + + LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d\n", + csi_report->CSI_report_bitlen.cri_ssbri_bitlen, + csi_report->CSI_report_bitlen.rsrp_bitlen, + csi_report->CSI_report_bitlen.diff_rsrp_bitlen); } - if (0 != UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report){ - uint8_t nb_ssb_resources =0; + uint8_t ri_restriction; + uint8_t ri_bitlen; + uint8_t nb_allowed_ri; + uint8_t max_ri; + + if (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI == reportQuantity_type || + NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI==reportQuantity_type || + NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI==reportQuantity_type || + NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI==reportQuantity_type|| + NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1==reportQuantity_type){ + for ( csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) { - if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId == - *(csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])) { - ///We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig - if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == - csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.present ) { - if (NULL != csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.choice.disabled->nrofReportedRS) - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri = *(csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1; - else - /*! From Spec 38.331 - * nrofReportedRS - * The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE - * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report. - * When the field is absent the UE applies the value 1 - */ - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri= 1; - } else - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri= 2; + if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_ssb_idx]->nzp_CSI_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { + ///For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212 + nb_ssb_resources= csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_ssb_idx]->nzp_CSI_RS_Resources.list.count; + csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_ssb_idx]->nzp_CSI_RS_Resources.list.array; + csi_report->SSB_Index_list = NULL; + } + break; + } + csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2 (nb_ssb_resources)); - nb_ssb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.count; - if (nb_ssb_resources){ - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen =ceil(log2 (nb_ssb_resources)); - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP - } - else{ - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen =0; - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen = 0; - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =0; - } + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.present){ - LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d\n", - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen, - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen, - UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen); - break ; + switch (RC.nrmac[Mod_idP]->config[0].carrier_config.num_tx_ant.value) { + case 1:; + csi_report->csi_meas_bitlen.ri_bitlen=0; + break; + case 2: + /* From Spec 38.212 + * If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator + * values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6, + * TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause + * 5.2.2.2.1 [6, TS 38.214]. + * + * But from Current RRC ASN structures nrofCQIsPerReport is not present. Present a dummy variable is present so using it to + * calculate RI for antennas equal or more than two. + * */ + AssertFatal (NULL!=csi_reportconfig->dummy, "nrofCQIsPerReport is not present"); + + ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; + + /* Replace dummy with the nrofCQIsPerReport from the CSIreport + config when equalent ASN structure present */ + if (0==*(csi_reportconfig->dummy)){ + nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0), &max_ri); + ri_bitlen = ceil(log2(nb_allowed_ri)); + } + else{ + nb_allowed_ri = number_of_bits_set(ri_restriction, &max_ri); + ri_bitlen = ceil(log2(nb_allowed_ri)); + } + ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel + csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + break; + case 4: + AssertFatal (NULL!=csi_reportconfig->dummy, "nrofCQIsPerReport is not present"); + + ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; + + /* Replace dummy with the nrofCQIsPerReport from the CSIreport + config when equalent ASN structure present */ + if (0==*(csi_reportconfig->dummy)){ + nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0), &max_ri); + ri_bitlen = ceil(log2(nb_allowed_ri)); + } + else{ + nb_allowed_ri = number_of_bits_set(ri_restriction,&max_ri); + ri_bitlen = ceil(log2(nb_allowed_ri)); + } + ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel + csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + break; + case 6: + case 8: + AssertFatal (NULL!=csi_reportconfig->dummy, "nrofCQIsPerReport is not present"); + + ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; + + /* Replace dummy with the nrofCQIsPerReport from the CSIreport + config when equalent ASN structure present */ + if (0==*(csi_reportconfig->dummy)){ + nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0),&max_ri); + ri_bitlen = ceil(log2(nb_allowed_ri)); + } + else{ + nb_allowed_ri = number_of_bits_set(ri_restriction, &max_ri); + ri_bitlen = ceil(log2(nb_allowed_ri)); + } + csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + break; + default: + AssertFatal(RC.nrmac[Mod_idP]->config[0].carrier_config.num_tx_ant.value>8,"Number of antennas %d are out of range", RC.nrmac[Mod_idP]->config[0].carrier_config.num_tx_ant.value); + } + } + csi_report->csi_meas_bitlen.li_bitlen=0; + csi_report->csi_meas_bitlen.cqi_bitlen=0; + csi_report->csi_meas_bitlen.pmi_x1_bitlen=0; + csi_report->csi_meas_bitlen.pmi_x2_bitlen=0; + } + + if( NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI==reportQuantity_type ){ + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.present){ + + switch (RC.nrmac[Mod_idP]->config[0].carrier_config.num_tx_ant.value) { + case 1:; + csi_report->csi_meas_bitlen.li_bitlen=0; + break; + case 2: + case 4: + case 6: + case 8: + /* From Spec 38.212 + * If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator + * values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6, + * TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause + * 5.2.2.2.1 [6, TS 38.214]. + * + * But from Current RRC ASN structures nrofCQIsPerReport is not present. Present a dummy variable is present so using it to + * calculate RI for antennas equal or more than two. + * */ + //! TODO: The bit length of LI is as follows LI = log2(RI), Need to confirm wheather we should consider maximum RI can be reported from ri_restricted + // or we should consider reported RI. If we need to consider reported RI for calculating LI bit length then we need to modify the code. + csi_report->csi_meas_bitlen.li_bitlen=ceil(log2(max_ri))<2?ceil(log2(max_ri)):2; + break; + default: + AssertFatal(RC.nrmac[Mod_idP]->config[0].carrier_config.num_tx_ant.value>8,"Number of antennas %d are out of range", RC.nrmac[Mod_idP]->config[0].carrier_config.num_tx_ant.value); + } + } + } + + if (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI == reportQuantity_type || + NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI==reportQuantity_type || + NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI==reportQuantity_type || + NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI==reportQuantity_type){ + + switch (RC.nrmac[Mod_idP]->config[0].carrier_config.num_tx_ant.value){ + case 1: + case 2: + case 4: + case 6: + case 8: + /* From Spec 38.212 + * If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator + * values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6, + * TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause + * 5.2.2.2.1 [6, TS 38.214]. + * + * But from Current RRC ASN structures nrofCQIsPerReport is not present. Present a dummy variable is present so using it to + * calculate RI for antennas equal or more than two. + * */ + + if (max_ri > 4 && max_ri < 8){ + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.present){ + if (NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI==csi_reportconfig->reportFreqConfiguration->cqi_FormatIndicator) + csi_report->csi_meas_bitlen.cqi_bitlen = 8; + else + csi_report->csi_meas_bitlen.cqi_bitlen = 4; + } + }else{ //This condition will work even for type1-multipanel. + if (NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI==csi_reportconfig->reportFreqConfiguration->cqi_FormatIndicator) + csi_report->csi_meas_bitlen.cqi_bitlen = 4; + else + csi_report->csi_meas_bitlen.cqi_bitlen = 2; + } + break; + default: + AssertFatal(RC.nrmac[Mod_idP]->config[0].carrier_config.num_tx_ant.value>8,"Number of antennas %d are out of range", RC.nrmac[Mod_idP]->config[0].carrier_config.num_tx_ant.value); + } + } + if (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI == reportQuantity_type || + NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI==reportQuantity_type){ + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.present){ + switch (csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present){ + case NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two: + if (max_ri ==1) + csi_report->csi_meas_bitlen.pmi_x1_bitlen = 2; + else if (max_ri ==2) + csi_report->csi_meas_bitlen.pmi_x1_bitlen = 1; + break; + default: + AssertFatal(csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present!= + NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two, + "Not handled Yet %d", csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present); + break; } } } - if (0 != UE_info->csi_report_template[UE_id][csi_report_id].nb_of_nzp_csi_report) - AssertFatal(1==0,"Currently configuring only SSB beamreporting."); break; } } @@ -180,12 +436,27 @@ void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t } -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; +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; + L1_RSRP_bitlen_t * CSI_report_bitlen = NULL; + CSI_Meas_bitlen_t * csi_meas_bitlen = NULL; + + if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP==UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type|| + NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type){ + CSI_report_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements + 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 ))); + } else{ + csi_meas_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements + csi_bitlen+= (csi_meas_bitlen->cri_bitlen +csi_meas_bitlen->ri_bitlen+csi_meas_bitlen->li_bitlen+csi_meas_bitlen->cqi_bitlen+csi_meas_bitlen->pmi_x1_bitlen+csi_meas_bitlen->pmi_x2_bitlen); + } + + return csi_bitlen; } @@ -243,7 +514,7 @@ void nr_csi_meas_reporting(int Mod_idP, 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]); + nr_get_csi_bitlen(Mod_idP,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]; @@ -311,6 +582,375 @@ static void handle_dl_harq(module_id_t mod_id, } } +int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, int Mod_idP, int UE_id) { + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id] ; + int nb_tci_states = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count; + NR_TCI_State_t *tci =NULL; + int i; + + for(i=0; ispCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i]; + + if(tci != NULL) { + if(tci->qcl_Type1.referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) { + if(tci->qcl_Type1.referenceSignal.choice.ssb == ssb_index_t) + return tci->tci_StateId; // returned TCI state ID + } + // if type2 is configured + else if(tci->qcl_Type2 != NULL && tci->qcl_Type2->referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) { + if(tci->qcl_Type2->referenceSignal.choice.ssb == ssb_index_t) + return tci->tci_StateId; // returned TCI state ID + } else LOG_I(MAC,"SSB index is not found in first 64 TCI states of TCI_statestoAddModList[%d]", i); + } + } + + // tci state not identified in first 64 TCI States of PDSCH Config + return -1; +} + +int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, int Mod_idP, int UE_id) { + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id] ; + int nb_tci_states = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count; + NR_TCI_State_t *tci =NULL; + NR_TCI_StateId_t *tci_id = NULL; + int bwp_id = 1; + NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + NR_ControlResourceSet_t *coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[bwp_id-1]; + int i; + int flag = 0; + int tci_stateID = -1; + + for(i=0; ispCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i]; + + if(tci != NULL && tci->qcl_Type1.referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) { + if(tci->qcl_Type1.referenceSignal.choice.ssb == ssb_index_t) { + flag = 1; + tci_stateID = tci->tci_StateId; + break; + } else if(tci->qcl_Type2 != NULL && tci->qcl_Type2->referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) { + flag = 1; + tci_stateID = tci->tci_StateId; + break; + } + } + + if(flag != 0 && tci_stateID != -1 && coreset != NULL) { + for(i=0; i<64 && itci_StatesPDCCH_ToAddList->list.count; i++) { + tci_id = coreset->tci_StatesPDCCH_ToAddList->list.array[i]; + + if(tci_id != NULL && *tci_id == tci_stateID) + return tci_stateID; + } + } + } + + // Need to implement once configuration is received + return -1; +} + +//returns the measured RSRP value (upper limit) +int get_measured_rsrp(uint8_t index) { + //if index is invalid returning minimum rsrp -140 + if((index >= 0 && index <= 15) || index >= 114) + return MIN_RSRP_VALUE; + + return L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[index]; +} + +//returns the differential RSRP value (upper limit) +int get_diff_rsrp(uint8_t index, int strongest_rsrp) { + if(strongest_rsrp != -1) { + return strongest_rsrp + diff_rsrp_ssb_csi_meas_10_1_6_1_2[index]; + } else + return MIN_RSRP_VALUE; +} + +//identifies the target SSB Beam index +//keeps the required date for PDCCH and PDSCH TCI state activation/deactivation CE consutruction globally +//handles triggering of PDCCH and PDSCH MAC CEs +void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) { + + int strongest_ssb_rsrp = 0; + int cqi_idx = 0; + int curr_ssb_beam_index = 0; //ToDo: yet to know how to identify the serving ssb beam index + uint8_t target_ssb_beam_index = curr_ssb_beam_index; + uint8_t is_triggering_ssb_beam_switch =0; + uint8_t ssb_idx = 0; + int pdsch_bwp_id =0; + int ssb_index[MAX_NUM_SSB] = {0}; + int ssb_rsrp[MAX_NUM_SSB] = {0}; + uint8_t idx = 0; + int bwp_id = 1; + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; + NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + //bwp indicator + int n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; + uint8_t nr_ssbri_cri = 0; + uint8_t nb_of_csi_ssb_report = UE_info->csi_report_template[UE_id][cqi_idx].nb_of_csi_ssb_report; + int better_rsrp_reported = -140-(-0); /*minimum_measured_RSRP_value - minimum_differntail_RSRP_value*///considering the minimum RSRP value as better RSRP initially + uint8_t diff_rsrp_idx = 0; + uint8_t i, j; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; + + if (n_dl_bwp < 4) + pdsch_bwp_id = bwp_id; + else + pdsch_bwp_id = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212 + + /*Example: + CRI_SSBRI: 1 2 3 4| 5 6 7 8| 9 10 1 2| + nb_of_csi_ssb_report = 3 //3 sets as above + nr_ssbri_cri = 4 //each set has 4 elements + storing ssb indexes in ssb_index array as ssb_index[0] = 1 .. ssb_index[4] = 5 + ssb_rsrp[0] = strongest rsrp in first set, ssb_rsrp[4] = strongest rsrp in second set, .. + idx: resource set index + */ + + //for all reported SSB + for (idx = 0; idx < nb_of_csi_ssb_report; idx++) { + nr_ssbri_cri = sched_ctrl->CSI_report[idx].choice.ssb_cri_report.nr_ssbri_cri; + //extracting the ssb indexes + for (ssb_idx = 0; ssb_idx < nr_ssbri_cri; ssb_idx++) { + ssb_index[idx * nb_of_csi_ssb_report + ssb_idx] = sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI[ssb_idx]; + } + + //if strongest measured RSRP is configured + strongest_ssb_rsrp = get_measured_rsrp(sched_ctrl->CSI_report[idx].choice.ssb_cri_report.RSRP); + // including ssb rsrp in mac stats + stats->cumul_rsrp += strongest_ssb_rsrp; + stats->num_rsrp_meas++; + ssb_rsrp[idx * nb_of_csi_ssb_report] = strongest_ssb_rsrp; + LOG_D(MAC,"ssb_rsrp = %d\n",strongest_ssb_rsrp); + + //if current ssb rsrp is greater than better rsrp + if(ssb_rsrp[idx * nb_of_csi_ssb_report] > better_rsrp_reported) { + better_rsrp_reported = ssb_rsrp[idx * nb_of_csi_ssb_report]; + target_ssb_beam_index = idx * nb_of_csi_ssb_report; + } + + for(diff_rsrp_idx =1; diff_rsrp_idx < nr_ssbri_cri; diff_rsrp_idx++) { + ssb_rsrp[idx * nb_of_csi_ssb_report + diff_rsrp_idx] = get_diff_rsrp(sched_ctrl->CSI_report[idx].choice.ssb_cri_report.diff_RSRP[diff_rsrp_idx-1], strongest_ssb_rsrp); + + //if current reported rsrp is greater than better rsrp + if(ssb_rsrp[idx * nb_of_csi_ssb_report + diff_rsrp_idx] > better_rsrp_reported) { + better_rsrp_reported = ssb_rsrp[idx * nb_of_csi_ssb_report + diff_rsrp_idx]; + target_ssb_beam_index = idx * nb_of_csi_ssb_report + diff_rsrp_idx; + } + } + } + + + if(ssb_index[target_ssb_beam_index] != ssb_index[curr_ssb_beam_index] && ssb_rsrp[target_ssb_beam_index] > ssb_rsrp[curr_ssb_beam_index]) { + if( ssb_rsrp[target_ssb_beam_index] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) { + is_triggering_ssb_beam_switch = 1; + LOG_D(MAC, "Triggering ssb beam switching using tci\n"); + } + } + + if(is_triggering_ssb_beam_switch) { + //filling pdcch tci state activativation mac ce structure fields + sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.is_scheduled = 1; + //OAI currently focusing on Non CA usecase hence 0 is considered as serving + //cell id + sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.servingCellId = 0; //0 for PCell as 38.331 v15.9.0 page 353 //serving cell id for which this MAC CE applies + sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.coresetId = 0; //coreset id for which the TCI State id is being indicated + + /* 38.321 v15.8.0 page 66 + TCI State ID: This field indicates the TCI state identified by TCI-StateId as specified in TS 38.331 [5] applicable + to the Control Resource Set identified by CORESET ID field. + If the field of CORESET ID is set to 0, + this field indicates a TCI-StateId for a TCI state of the first 64 TCI-states configured by tci-States-ToAddModList and tciStates-ToReleaseList in the PDSCH-Config in the active BWP. + If the field of CORESET ID is set to the other value than 0, + this field indicates a TCI-StateId configured by tci-StatesPDCCH-ToAddList and tciStatesPDCCH-ToReleaseList in the controlResourceSet identified by the indicated CORESET ID. + The length of the field is 7 bits + */ + if(sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.coresetId == 0) { + int tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index[target_ssb_beam_index], Mod_idP, UE_id); + + if( tci_state_id != -1) + sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id; + else { + //identify the best beam within first 64 TCI States of PDSCH + //Config TCI-states-to-addModList + int flag = 0; + + for(i =0; ssb_index_sorted[i]!=0; i++) { + tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index_sorted[i], Mod_idP, UE_id) ; + + if(tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) { + sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id; + flag = 1; + break; + } + } + + if(flag == 0 || ssb_rsrp_sorted[i] < ssb_rsrp[curr_ssb_beam_index] || ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] < L1_RSRP_HYSTERIS) { + sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.is_scheduled = 0; + } + } + } else { + int tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index[target_ssb_beam_index], Mod_idP, UE_id); + + if (tci_state_id !=-1) + sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id; + else { + //identify the best beam within CORESET/PDCCH + ////Config TCI-states-to-addModList + int flag = 0; + + for(i =0; ssb_index_sorted[i]!=0; i++) { + tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index_sorted[i], Mod_idP, UE_id); + + if( tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) { + sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id; + flag = 1; + break; + } + } + + if(flag == 0 || ssb_rsrp_sorted[i] < ssb_rsrp[curr_ssb_beam_index] || ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] < L1_RSRP_HYSTERIS) { + sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.is_scheduled = 0; + } + } + } + + sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tci_present_inDCI = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[bwp_id-1]->tci_PresentInDCI; + + //filling pdsch tci state activation deactivation mac ce structure fields + if(sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tci_present_inDCI) { + sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.is_scheduled = 1; + /* + Serving Cell ID: This field indicates the identity of the Serving Cell for which the MAC CE applies + Considering only PCell exists. Serving cell index of PCell is always 0, hence configuring 0 + */ + sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.servingCellId = 0; + /* + BWP ID: This field indicates a DL BWP for which the MAC CE applies as the codepoint of the DCI bandwidth + part indicator field as specified in TS 38.212 + */ + sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.bwpId = pdsch_bwp_id; + + /* + * TODO ssb_rsrp_sort() API yet to code to find 8 best beams, rrc configuration + * is required + */ + for(i = 0; i<8; i++) { + sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.tciStateActDeact[i] = i; + } + + sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.highestTciStateActivated = 8; + + for(i = 0, j =0; iUE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.tciStateActDeact[i]) { + sched_ctrl->UE_mac_ce_ctrl.pdsch_TCI_States_ActDeact.codepoint[j] = i; + j++; + } + } + }//tci_presentInDCI + }//is-triggering_beam_switch +}//tci handling + +void reverse_n_bits(uint8_t *value, uint16_t bitlen) { + uint16_t j; + uint8_t i; + for(j = bitlen - 1,i = 0; j > i; j--, i++) { + if(((*value>>j)&1) != ((*value>>i)&1)) { + *value ^= (1<csi_part1.csi_part1_bit_len)/8); + uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload; + NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type = NR_CSI_ReportConfig__reportQuantity_PR_NOTHING; + NR_UE_info_t *UE_info = &(RC.nrmac[Mod_idP]->UE_info); + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + uint8_t csi_report_id = 0; + + UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report = 0; + for ( csi_report_id =0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++ ) { + //Has to implement according to reportSlotConfig type + /*reportQuantity must be considered according to the current scheduled + CSI-ReportConfig if multiple CSI-ReportConfigs present*/ + reportQuantity_type = UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type; + LOG_D(PHY,"SFN/SF:%d%d reportQuantity type = %d\n",frame,slot,reportQuantity_type); + + if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type || + NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP == reportQuantity_type) { + uint8_t csi_ssb_idx = 0; + uint8_t diff_rsrp_idx = 0; + uint8_t cri_ssbri_bitlen = UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen.cri_ssbri_bitlen; + + /*! As per the spec 38.212 and table: 6.3.1.1.2-12 in a single UCI sequence we can have multiple CSI_report + * the number of CSI_report will depend on number of CSI resource sets that are configured in CSI-ResourceConfig RRC IE + * From spec 38.331 from the IE CSI-ResourceConfig for SSB RSRP reporting we can configure only one resource set + * From spec 38.214 section 5.2.1.2 For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 + */ + + /** from 38.214 sec 5.2.1.4.2 + - if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'disabled', the UE is + not required to update measurements for more than 64 CSI-RS and/or SSB resources, and the UE shall report in + a single report nrofReportedRS (higher layer configured) different CRI or SSBRI for each report setting + + - if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'enabled', the UE is not + required to update measurements for more than 64 CSI-RS and/or SSB resources, and the UE shall report in a + single reporting instance two different CRI or SSBRI for each report setting, where CSI-RS and/or SSB + resources can be received simultaneously by the UE either with a single spatial domain receive filter, or with + multiple simultaneous spatial domain receive filter + */ + + idx = 0; //Since for SSB RSRP reporting in RRC can configure only one ssb resource set per one report config + sched_ctrl->CSI_report[idx].choice.ssb_cri_report.nr_ssbri_cri = UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen.nb_ssbri_cri; + + for (csi_ssb_idx = 0; csi_ssb_idx < sched_ctrl->CSI_report[idx].choice.ssb_cri_report.nr_ssbri_cri ; csi_ssb_idx++) { + if(cri_ssbri_bitlen > 1) + reverse_n_bits(payload, cri_ssbri_bitlen); + + if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type) + sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] = + *(UE_info->csi_report_template[UE_id][csi_report_id].SSB_Index_list[cri_ssbri_bitlen>0?((*payload)&~(~1<<(cri_ssbri_bitlen-1))):cri_ssbri_bitlen]); + else + sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] = + *(UE_info->csi_report_template[UE_id][csi_report_id].CSI_Index_list[cri_ssbri_bitlen>0?((*payload)&~(~1<<(cri_ssbri_bitlen-1))):cri_ssbri_bitlen]); + + *payload >>= cri_ssbri_bitlen; + LOG_D(PHY,"SSB_index = %d\n",sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx]); + } + + reverse_n_bits(payload, 7); + sched_ctrl->CSI_report[idx].choice.ssb_cri_report.RSRP = (*payload) & 0x7f; + *payload >>= 7; + + for ( diff_rsrp_idx =0; diff_rsrp_idx < sched_ctrl->CSI_report[idx].choice.ssb_cri_report.nr_ssbri_cri - 1; diff_rsrp_idx++ ) { + reverse_n_bits(payload,4); + sched_ctrl->CSI_report[idx].choice.ssb_cri_report.diff_RSRP[diff_rsrp_idx] = (*payload) & 0x0f; + *payload >>= 4; + } + UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report++; + LOG_D(MAC,"csi_payload size = %d, rsrp_id = %d\n",payload_size, sched_ctrl->CSI_report[idx].choice.ssb_cri_report.RSRP); + } + } + + if ( !(reportQuantity_type)) + AssertFatal(reportQuantity_type, "reportQuantity is not configured"); + +} + void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, sub_frame_t slot, @@ -373,6 +1013,7 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, LOG_E(MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti); return; } + NR_CSI_MeasConfig_t *csi_MeasConfig = RC.nrmac[mod_id]->UE_info.secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; 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]; @@ -412,6 +1053,15 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, handle_dl_harq(mod_id, UE_id, pid, uci_234->harq.harq_crc != 1 && acknack); } } + if ((uci_234->pduBitmap >> 2) & 0x01) { + //API to parse the csi report and store it into sched_ctrl + extract_pucch_csi_report (csi_MeasConfig, uci_234, frame, slot, UE_id, mod_id); + //TCI handling function + tci_handling(mod_id, UE_id,frame, slot); + } + if ((uci_234->pduBitmap >> 3) & 0x01) { + //@TODO:Handle CSI Report 2 + } } @@ -742,5 +1392,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 90a1811b22..9784b6b79e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -137,10 +137,10 @@ void nr_process_mac_pdu( 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 BSR value */ + //38.321 section 6.1.3.1 + //fixed length + mac_ce_len =1; + /* 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; @@ -182,7 +182,7 @@ void nr_process_mac_pdu( NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]]; } - break; + break; case UL_SCH_LCID_C_RNTI: //38.321 section 6.1.3.2 @@ -395,7 +395,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, 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", + LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d sduP %p\n", gnb_mod_idP, harq_pid, CC_idP, @@ -403,7 +403,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, slotP, current_rnti, UE_id, - ul_cqi); + ul_cqi, + sduP); // if not missed detection (10dB threshold for now) if (UE_scheduling_control->ul_rssi < (100+rssi)) { @@ -411,7 +412,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (timing_advance != 0xffff) UE_scheduling_control->ta_update = timing_advance; UE_scheduling_control->ul_rssi = rssi; - LOG_D(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); + LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); } else{ UE_scheduling_control->tpc0 = 1; @@ -430,9 +431,10 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, #endif if (sduP != NULL){ - LOG_D(MAC, "Received PDU at MAC gNB \n"); + LOG_D(NR_MAC, "Received PDU at MAC gNB \n"); - UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes; + const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; + UE_scheduling_control->sched_ul_bytes -= tb_size; if (UE_scheduling_control->sched_ul_bytes < 0) UE_scheduling_control->sched_ul_bytes = 0; @@ -442,7 +444,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, 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; + const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; + UE_scheduling_control->sched_ul_bytes -= tb_size; if (UE_scheduling_control->sched_ul_bytes < 0) UE_scheduling_control->sched_ul_bytes = 0; } @@ -465,7 +468,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, // random access pusch with TC-RNTI if (ra->rnti != current_rnti) { - LOG_W(MAC, + LOG_W(NR_MAC, "expected TC-RNTI %04x to match current RNTI %04x\n", ra->rnti, current_rnti); @@ -473,19 +476,25 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } 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, + LOG_I(NR_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); + + LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n"); + for (int k = 0; k < sdu_lenP; k++) { + LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]); + } + // 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, + LOG_I(NR_MAC, "reset RA state information for RA-RNTI %04x/index %d\n", ra->rnti, i); @@ -862,7 +871,7 @@ void nr_schedule_ulsch(module_id_t module_id, /* 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}; + 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; @@ -916,6 +925,7 @@ void nr_schedule_ulsch(module_id_t module_id, /* 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; + sched_ctrl->sched_ul_bytes += sched_pusch->tb_size; } else { LOG_D(MAC, "%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n", @@ -929,7 +939,6 @@ void nr_schedule_ulsch(module_id_t module_id, 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", @@ -1055,18 +1064,16 @@ void nr_schedule_ulsch(module_id_t module_id, /* 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); + bool valid_ptrs_setup = false; 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 + valid_ptrs_setup = set_ul_ptrs_values(ps->NR_DMRS_UplinkConfig->phaseTrackingRS->choice.setup, + pusch_pdu->rb_size, pusch_pdu->mcs_index, pusch_pdu->mcs_table, + &pusch_pdu->pusch_ptrs.ptrs_freq_density,&pusch_pdu->pusch_ptrs.ptrs_time_density, + &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset,&pusch_pdu->pusch_ptrs.num_ptrs_ports, + &pusch_pdu->pusch_ptrs.ul_ptrs_power, pusch_pdu->nr_of_symbols); + if (valid_ptrs_setup==true) { + 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 diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 26d29f9412..f552b6c606 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -41,13 +41,16 @@ void set_cset_offset(uint16_t); void mac_top_init_gNB(void); void config_common(int Mod_idP, + int ssb_SubcarrierOffset, int pdsch_AntennaPorts, + int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc ); -int rrc_mac_config_req_gNB(module_id_t Mod_idP, - int ssb_SubcarrierOffset, +int rrc_mac_config_req_gNB(module_id_t Mod_idP, + int ssb_SubcarrierOffset, int pdsch_AntennaPorts, + int pusch_AntennaPorts, int pusch_tgt_snrx10, int pucch_tgt_snrx10, NR_ServingCellConfigCommon_t *scc, @@ -70,9 +73,11 @@ void nr_schedule_ue_spec(module_id_t module_id, void schedule_control_sib1(module_id_t module_id, int CC_id, + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, int time_domain_allocation, uint8_t mcsTableIdx, uint8_t mcs, + uint8_t candidate_idx, int num_total_bytes); void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); @@ -82,7 +87,11 @@ 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); +void schedule_nr_mib(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP, + uint8_t slots_per_frame, + int nb_periods_per_frame); /// uplink scheduler void nr_schedule_ulsch(module_id_t module_id, @@ -123,7 +132,8 @@ void nr_get_Msg3alloc(module_id_t module_id, NR_BWP_Uplink_t *ubwp, sub_frame_t current_subframe, frame_t current_frame, - NR_RA_t *ra); + NR_RA_t *ra, + int16_t *tdd_beam_association); /* \brief Function in gNB to fill RAR pdu when requested by PHY. @param ra Instance of RA resources of gNB @@ -261,7 +271,6 @@ NR_SearchSpace_t *get_searchspace( NR_BWP_Downlink_t *bwp, NR_SearchSpace__searchSpaceType_PR target_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, @@ -328,7 +337,7 @@ uint16_t compute_pucch_prb_size(uint8_t format, uint8_t n_symb, uint8_t n_re_ctrl); -void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t *UE_info, int UE_id); +void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_info, int UE_id, module_id_t Mod_idP); int get_dlscs(nfapi_nr_config_request_t *cfg); @@ -346,11 +355,7 @@ void config_nr_mib(int Mod_idP, int cellBarred, int intraFreqReselection); - -void nr_generate_Msg2(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t slotP); +void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra); void nr_process_mac_pdu( module_id_t module_idP, @@ -364,7 +369,7 @@ 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); +void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id); /* \brief Function to indicate a received SDU on ULSCH. diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 8dc1303801..33e575d2b9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -96,7 +96,7 @@ void mac_top_init_gNB(void) // These should be out of here later pdcp_layer_init(); - if(IS_SOFTMODEM_NOS1 && !get_softmodem_params()->do_ra) + if(IS_SOFTMODEM_NOS1 && !(get_softmodem_params()->do_ra || get_softmodem_params()->sa) ) nr_DRB_preconfiguration(0x1234); rrc_init_nr_global_param(); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index bca974a00f..d9869e7a7b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -194,8 +194,6 @@ typedef struct { uint32_t PCCH_alloc_pdu; /// Outgoing PCCH pdu for PHY PCCH_PDU PCCH_pdu; - /// Outgoing RAR pdu for PHY - RAR_PDU RAR_pdu; /// Template for RA computations NR_RA_t ra[NR_NB_RA_PROC_MAX]; /// VRB map for common channels @@ -215,6 +213,8 @@ typedef struct { uint8_t max_association_period; //SSB index uint8_t ssb_index[MAX_NUM_OF_SSB]; + //CB preambles for each SSB + uint8_t cb_preambles_per_ssb; } NR_COMMON_channels_t; @@ -246,8 +246,17 @@ typedef struct pdcchStateInd { uint8_t servingCellId; uint8_t coresetId; uint8_t tciStateId; + bool tci_present_inDCI; } pdcchStateInd_t; +typedef struct pucchSpatialRelation { + bool is_scheduled; + uint8_t servingCellId; + uint8_t bwpId; + uint8_t pucchResourceId; + bool s0tos7_actDeact[8]; +} pucchSpatialRelation_t; + typedef struct SPCSIReportingpucch { bool is_scheduled; uint8_t servingCellId; @@ -271,12 +280,14 @@ typedef struct pdschTciStatesActDeact { uint8_t bwpId; uint8_t highestTciStateActivated; bool tciStateActDeact[MAX_TCI_STATES]; + uint8_t codepoint[8]; } pdschTciStatesActDeact_t; typedef struct UE_info { sp_zp_csirs_t sp_zp_csi_rs; csi_rs_im_t csi_im; pdcchStateInd_t pdcch_state_ind; + pucchSpatialRelation_t pucch_spatial_relation; SPCSIReportingpucch_t SP_CSI_reporting_pucch; aperiodicCSI_triggerStateSelection_t aperi_CSI_trigger; pdschTciStatesActDeact_t pdsch_TCI_States_ActDeact; @@ -352,6 +363,84 @@ typedef struct NR_UE_harq { uint32_t tb_size; } NR_UE_harq_t; +//! fixme : need to enhace for the multiple TB CQI report + + +// +/*! As per spec 38.214 section 5.2.1.4.2 + * - if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'disabled', the UE shall report in + a single report nrofReportedRS (higher layer configured) different CRI or SSBRI for each report setting. + * - if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'enabled', the UE shall report in a + single reporting instance two different CRI or SSBRI for each report setting, where CSI-RS and/or SSB + resources can be received simultaneously by the UE either with a single spatial domain receive filter, or with + multiple simultaneous spatial domain receive filter +*/ +#define MAX_NR_OF_REPORTED_RS 4 + +typedef enum NR_CSI_Report_Config { + CSI_Report_PR_cri_ri_li_pmi_cqi_report, + CSI_Report_PR_ssb_cri_report +} NR_CSI_Report_Config_PR; +struct CRI_RI_LI_PMI_CQI { + uint8_t cri; + uint8_t ri; + uint8_t li; + uint8_t pmi_x1; + uint8_t pmi_x2; + uint8_t cqi; +}; + +typedef struct CRI_SSB_RSRP { + uint8_t nr_ssbri_cri; + uint8_t CRI_SSBRI[MAX_NR_OF_REPORTED_RS]; + uint8_t RSRP; + uint8_t diff_RSRP[MAX_NR_OF_REPORTED_RS - 1]; +} CRI_SSB_RSRP_t; + +struct CSI_Report { + NR_CSI_Report_Config_PR present; + union Config_CSI_Report { + struct CRI_RI_LI_PMI_CQI cri_ri_li_pmi_cqi_report; + struct CRI_SSB_RSRP ssb_cri_report; + } choice; +}; + +#define MAX_SR_BITLEN 8 + +typedef struct { + uint8_t nb_ssbri_cri; + uint8_t cri_ssbri_bitlen; + uint8_t rsrp_bitlen; + uint8_t diff_rsrp_bitlen; +}L1_RSRP_bitlen_t; + +typedef struct{ + uint8_t cri_bitlen; + uint8_t ri_bitlen; + uint8_t li_bitlen; + uint8_t pmi_x1_bitlen; + uint8_t pmi_x2_bitlen; + uint8_t cqi_bitlen; +} CSI_Meas_bitlen_t; + +typedef struct nr_csi_report { + NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; + long periodicity; + uint16_t offset; + long ** SSB_Index_list; + long ** CSI_Index_list; +// uint8_t nb_of_nzp_csi_report; + uint8_t nb_of_csi_ssb_report; + L1_RSRP_bitlen_t CSI_report_bitlen; + CSI_Meas_bitlen_t csi_meas_bitlen; +} nr_csi_report_t; + +/*! As per the spec 38.212 and table: 6.3.1.1.2-12 in a single UCI sequence we can have multiple CSI_report + the number of CSI_report will depend on number of CSI resource sets that are configured in CSI-ResourceConfig RRC IE + From spec 38.331 from the IE CSI-ResourceConfig for SSB RSRP reporting we can configure only one resource set + From spec 38.214 section 5.2.1.2 For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 + */ +#define MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG 16 typedef struct NR_UE_old_sched { uint16_t rbSize; int time_domain_allocation; @@ -376,26 +465,8 @@ typedef struct NR_UE_ul_harq { NR_sched_pusch_t sched_pusch; } NR_UE_ul_harq_t; - -typedef struct { - uint8_t nb_ssbri_cri; - uint8_t cri_ssbri_bitlen; - uint8_t rsrp_bitlen; - uint8_t diff_rsrp_bitlen; -}CRI_SSBRI_RSRP_bitlen_t; - - -#define MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG 16 -typedef struct nr_csi_report { - NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; - NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR CSI_Resource_type; - uint8_t nb_of_nzp_csi_report; - uint8_t nb_of_csi_ssb_report; - CRI_SSBRI_RSRP_bitlen_t CSI_report_bitlen[MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG]; -} nr_csi_report_t; - - /*! \brief scheduling control information set through an API */ +#define MAX_CSI_REPORTS 48 typedef struct { /// total amount of data awaiting for this UE uint32_t num_total_bytes; @@ -450,6 +521,8 @@ typedef struct { uint8_t tpc0; uint8_t tpc1; uint16_t ul_rssi; + uint8_t current_harq_pid; + struct CSI_Report CSI_report[MAX_CSI_REPORTS]; /// information about every HARQ process NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES]; /// HARQ processes that are free @@ -487,6 +560,8 @@ typedef struct { int ulsch_total_bytes_scheduled; int ulsch_total_bytes_rx; int ulsch_current_bytes; + int cumul_rsrp; + uint8_t num_rsrp_meas; } NR_mac_stats_t; @@ -536,6 +611,8 @@ typedef struct gNB_MAC_INST_s { int pusch_target_snrx10; /// Pucch target SNR int pucch_target_snrx10; + /// Subcarrier Offset + int ssb_SubcarrierOffset; /// Common cell resources NR_COMMON_channels_t common_channels[NFAPI_CC_MAX]; /// current PDU index (BCH,DLSCH) @@ -589,11 +666,12 @@ 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]; + /// list of allocated beams per period + int16_t *tdd_beam_association; /// 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 @@ -601,7 +679,7 @@ typedef struct gNB_MAC_INST_s { NR_UE_sched_ctrl_t *sched_ctrlCommon; NR_CellGroupConfig_t *secondaryCellGroupCommon; - NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config; + NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64]; } gNB_MAC_INST; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 6f183d7bc3..9d7faf1674 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -2099,8 +2099,7 @@ pdcp_config_set_security( } //----------------------------------------------------------------------------- -void -rrc_pdcp_config_req ( +void rrc_pdcp_config_req ( const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, const uint32_t actionP, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index f3d4b16130..1822239171 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -21,24 +21,264 @@ #include "nr_pdcp_entity.h" -#include "nr_pdcp_entity_drb_am.h" +#include +#include +#include + +#include "nr_pdcp_security_nea2.h" +#include "nr_pdcp_integrity_nia2.h" +#include "nr_pdcp_sdu.h" #include "LOG/log.h" -nr_pdcp_entity_t *new_nr_pdcp_entity_srb( - int rb_id, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size), - 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) +static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, + char *_buffer, int size) { - abort(); + unsigned char *buffer = (unsigned char *)_buffer; + nr_pdcp_sdu_t *sdu; + int rcvd_sn; + uint32_t rcvd_hfn; + uint32_t rcvd_count; + int header_size; + int integrity_size; + int rx_deliv_sn; + uint32_t rx_deliv_hfn; + + if (size < 1) { + LOG_E(PDCP, "bad PDU received (size = %d)\n", size); + return; + } + + if (!(buffer[0] & 0x80)) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (entity->sn_size == 12) { + rcvd_sn = ((buffer[0] & 0xf) << 8) | + buffer[1]; + header_size = 2; + } else { + rcvd_sn = ((buffer[0] & 0x3) << 16) | + (buffer[1] << 8) | + buffer[2]; + header_size = 3; + } + + if (entity->has_integrity) { + integrity_size = 4; + } else { + integrity_size = 0; + } + + if (size < header_size + integrity_size + 1) { + LOG_E(PDCP, "bad PDU received (size = %d)\n", size); + return; + } + + rx_deliv_sn = entity->rx_deliv & entity->sn_max; + rx_deliv_hfn = (entity->rx_deliv >> entity->sn_size) & ~entity->sn_max; + + if (rcvd_sn < rx_deliv_sn - entity->window_size) { + rcvd_hfn = rx_deliv_hfn + 1; + } else if (rcvd_sn >= rx_deliv_sn + entity->window_size) { + rcvd_hfn = rx_deliv_hfn - 1; + } else { + rcvd_hfn = rx_deliv_hfn; + } + + rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn; + + if (entity->has_ciphering) + entity->cipher(entity->security_context, + buffer+header_size, size-header_size, + entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1); + + if (entity->has_integrity) { + unsigned char integrity[4]; + entity->integrity(entity->integrity_context, integrity, + buffer, size - integrity_size, + entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1); + if (memcmp(integrity, buffer, 4) != 0) { + LOG_E(PDCP, "discard NR PDU, integrity failed\n"); + return; + } + } + + if (rcvd_count < entity->rx_deliv + || nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) { + LOG_D(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count); + return; + } + + sdu = nr_pdcp_new_sdu(rcvd_count, + (char *)buffer + header_size, + size - header_size - integrity_size); + entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu); + entity->rx_size += size-header_size; + + if (rcvd_count >= entity->rx_next) { + entity->rx_next = rcvd_count + 1; + } + + /* TODO(?): out of order delivery */ + + if (rcvd_count == entity->rx_deliv) { + /* deliver all SDUs starting from rx_deliv up to discontinuity or end of list */ + uint32_t count = entity->rx_deliv; + while (entity->rx_list != NULL && count == entity->rx_list->count) { + nr_pdcp_sdu_t *cur = entity->rx_list; + entity->deliver_sdu(entity->deliver_sdu_data, entity, + cur->buffer, cur->size); + entity->rx_list = cur->next; + entity->rx_size -= cur->size; + nr_pdcp_free_sdu(cur); + count++; + } + entity->rx_deliv = count; + } + + if (entity->t_reordering_start != 0 && entity->rx_deliv > entity->rx_reord) { + /* stop and reset t-Reordering */ + entity->t_reordering_start = 0; + } + + if (entity->t_reordering_start == 0 && entity->rx_deliv < entity->rx_next) { + entity->rx_reord = entity->rx_next; + entity->t_reordering_start = entity->t_current; + } } -nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( - int rb_id, +static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity, + char *buffer, int size, int sdu_id) +{ + uint32_t count; + int sn; + int header_size; + int integrity_size; + char buf[size + 3 + 4]; + int dc_bit; + + count = entity->tx_next; + sn = entity->tx_next & entity->sn_max; + + /* D/C bit is only to be set for DRBs */ + if (entity->type == NR_PDCP_DRB_AM || entity->type == NR_PDCP_DRB_UM) { + dc_bit = 0x80; + } else { + dc_bit = 0; + } + + if (entity->sn_size == 12) { + buf[0] = dc_bit | ((sn >> 8) & 0xf); + buf[1] = sn & 0xff; + header_size = 2; + } else { + buf[0] = dc_bit | ((sn >> 16) & 0x3); + buf[1] = (sn >> 8) & 0xff; + buf[2] = sn & 0xff; + header_size = 3; + } + + if (entity->has_integrity) { + integrity_size = 4; + } else { + integrity_size = 0; + } + + memcpy(buf + header_size, buffer, size); + + if (entity->has_integrity) + entity->integrity(entity->integrity_context, + (unsigned char *)buf + header_size + size, + (unsigned char *)buf, header_size + size, + entity->rb_id, count, entity->is_gnb ? 1 : 0); + + if (entity->has_ciphering) + entity->cipher(entity->security_context, + (unsigned char *)buf + header_size, size + integrity_size, + entity->rb_id, count, entity->is_gnb ? 1 : 0); + + entity->tx_next++; + + entity->deliver_pdu(entity->deliver_pdu_data, entity, buf, + header_size + size + integrity_size, sdu_id); +} + +static void nr_pdcp_entity_set_integrity_key(nr_pdcp_entity_t *entity, + char *key) +{ + LOG_E(PDCP, "%s: %d: %s: TODO? to remove?\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + //memcpy(entity->integrity_key, key, 16); +} + +static void check_t_reordering(nr_pdcp_entity_t *entity) +{ + uint32_t count; + + if (entity->t_reordering_start == 0 + || entity->t_current <= entity->t_reordering_start + entity->t_reordering) + return; + + /* stop timer */ + entity->t_reordering_start = 0; + + /* deliver all SDUs with count < rx_reord */ + while (entity->rx_list != NULL && entity->rx_list->count < entity->rx_reord) { + nr_pdcp_sdu_t *cur = entity->rx_list; + entity->deliver_sdu(entity->deliver_sdu_data, entity, + cur->buffer, cur->size); + entity->rx_list = cur->next; + entity->rx_size -= cur->size; + nr_pdcp_free_sdu(cur); + } + + /* deliver all SDUs starting from rx_reord up to discontinuity or end of list */ + count = entity->rx_reord; + while (entity->rx_list != NULL && count == entity->rx_list->count) { + nr_pdcp_sdu_t *cur = entity->rx_list; + entity->deliver_sdu(entity->deliver_sdu_data, entity, + cur->buffer, cur->size); + entity->rx_list = cur->next; + entity->rx_size -= cur->size; + nr_pdcp_free_sdu(cur); + count++; + } + + entity->rx_deliv = count; + + if (entity->rx_deliv < entity->rx_next) { + entity->rx_reord = entity->rx_next; + entity->t_reordering_start = entity->t_current; + } +} + +void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now) +{ + entity->t_current = now; + + check_t_reordering(entity); +} + +void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity) +{ + nr_pdcp_sdu_t *cur = entity->rx_list; + while (cur != NULL) { + nr_pdcp_sdu_t *next = cur->next; + nr_pdcp_free_sdu(cur); + cur = next; + } + if (entity->free_security != NULL) + entity->free_security(entity->security_context); + if (entity->free_integrity != NULL) + entity->free_integrity(entity->integrity_context); + free(entity); +} + +nr_pdcp_entity_t *new_nr_pdcp_entity( + nr_pdcp_entity_type_t type, + int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -47,34 +287,71 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( void *deliver_pdu_data, int sn_size, int t_reordering, - int discard_timer) + int discard_timer, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { - nr_pdcp_entity_drb_am_t *ret; + nr_pdcp_entity_t *ret; - ret = calloc(1, sizeof(nr_pdcp_entity_drb_am_t)); + ret = calloc(1, sizeof(nr_pdcp_entity_t)); if (ret == NULL) { LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - ret->common.recv_pdu = nr_pdcp_entity_drb_am_recv_pdu; - ret->common.recv_sdu = nr_pdcp_entity_drb_am_recv_sdu; - ret->common.set_integrity_key = nr_pdcp_entity_drb_am_set_integrity_key; + ret->type = type; - ret->common.delete = nr_pdcp_entity_drb_am_delete; + ret->recv_pdu = nr_pdcp_entity_recv_pdu; + ret->recv_sdu = nr_pdcp_entity_recv_sdu; + ret->set_integrity_key = nr_pdcp_entity_set_integrity_key; + ret->set_time = nr_pdcp_entity_set_time; - ret->common.deliver_sdu = deliver_sdu; - ret->common.deliver_sdu_data = deliver_sdu_data; + ret->delete = nr_pdcp_entity_delete; - ret->common.deliver_pdu = deliver_pdu; - ret->common.deliver_pdu_data = deliver_pdu_data; + ret->deliver_sdu = deliver_sdu; + ret->deliver_sdu_data = deliver_sdu_data; + + ret->deliver_pdu = deliver_pdu; + ret->deliver_pdu_data = deliver_pdu_data; 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 = (1 << sn_size) - 1; + ret->sn_max = (1 << sn_size) - 1; + ret->window_size = 1 << (sn_size - 1); - return (nr_pdcp_entity_t *)ret; + if (ciphering_key != NULL && ciphering_algorithm != 0) { + if (ciphering_algorithm != 2) { + LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n"); + exit(1); + } + ret->has_ciphering = 1; + ret->ciphering_algorithm = ciphering_algorithm; + memcpy(ret->ciphering_key, ciphering_key, 16); + + ret->security_context = nr_pdcp_security_nea2_init(ciphering_key); + ret->cipher = nr_pdcp_security_nea2_cipher; + ret->free_security = nr_pdcp_security_nea2_free_security; + } + ret->is_gnb = is_gnb; + + if (integrity_key != NULL && integrity_algorithm != 0) { + if (integrity_algorithm != 2) { + LOG_E(PDCP, "FATAL: only nia2 supported for the moment\n"); + exit(1); + } + ret->has_integrity = 1; + ret->integrity_algorithm = integrity_algorithm; + memcpy(ret->integrity_key, integrity_key, 16); + + ret->integrity_context = nr_pdcp_integrity_nia2_init(integrity_key); + ret->integrity = nr_pdcp_integrity_nia2_integrity; + ret->free_integrity = nr_pdcp_integrity_nia2_free_integrity; + } + + return ret; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index ce5dd300e9..4ae7a45abb 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -19,18 +19,29 @@ * contact@openairinterface.org */ -#include - #ifndef _NR_PDCP_ENTITY_H_ #define _NR_PDCP_ENTITY_H_ +#include + +#include "nr_pdcp_sdu.h" + +typedef enum { + NR_PDCP_DRB_AM, + NR_PDCP_DRB_UM, + NR_PDCP_SRB +} nr_pdcp_entity_type_t; + typedef struct nr_pdcp_entity_t { + nr_pdcp_entity_type_t type; + /* functions provided by the PDCP module */ void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size); void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size, int sdu_id); void (*delete)(struct nr_pdcp_entity_t *entity); void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key); + void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now); /* callbacks provided to the PDCP module */ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, @@ -39,22 +50,61 @@ typedef struct nr_pdcp_entity_t { void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size, int sdu_id); void *deliver_pdu_data; - int tx_hfn; - int next_nr_pdcp_tx_sn; - int maximum_nr_pdcp_sn; + + /* configuration variables */ + int rb_id; + + int sn_size; /* SN size, in bits */ + int t_reordering; /* unit: ms */ + int discard_timer; /* unit: ms */ + + int sn_max; /* (2^SN_size) - 1 */ + int window_size; /* 2^(SN_size - 1) */ + + /* state variables */ + uint32_t tx_next; + uint32_t rx_next; + uint32_t rx_deliv; + uint32_t rx_reord; + + /* set to the latest know time by the user of the module. Unit: ms */ + uint64_t t_current; + + /* timers (stores the ms of activation, 0 means not active) */ + int t_reordering_start; + + /* security */ + int has_ciphering; + int has_integrity; + int ciphering_algorithm; + int integrity_algorithm; + unsigned char ciphering_key[16]; + unsigned char integrity_key[16]; + void *security_context; + void (*cipher)(void *security_context, + unsigned char *buffer, int length, + int bearer, int count, int direction); + void (*free_security)(void *security_context); + void *integrity_context; + void (*integrity)(void *integrity_context, unsigned char *out, + unsigned char *buffer, int length, + int bearer, int count, int direction); + void (*free_integrity)(void *integrity_context); + /* security/integrity algorithms need to know uplink/downlink information + * which is reverse for gnb and ue, so we need to know if this + * pdcp entity is for a gnb or an ue + */ + int is_gnb; + + /* rx management */ + nr_pdcp_sdu_t *rx_list; + int rx_size; + int rx_maxsize; } nr_pdcp_entity_t; -nr_pdcp_entity_t *new_nr_pdcp_entity_srb( - int rb_id, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size), - 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); - -nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( - int rb_id, +nr_pdcp_entity_t *new_nr_pdcp_entity( + nr_pdcp_entity_type_t type, + int is_gnb, int rb_id, void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size), void *deliver_sdu_data, @@ -63,7 +113,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( void *deliver_pdu_data, int sn_size, int t_reordering, - int discard_timer); + int discard_timer, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key); void nr_DRB_preconfiguration(uint16_t crnti); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c deleted file mode 100644 index f2f849b9e3..0000000000 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.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 "nr_pdcp_entity_drb_am.h" - -#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)) - 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); -} - -void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size, - int sdu_id) -{ - nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; - int sn; - char buf[size+3]; - - sn = entity->common.next_nr_pdcp_tx_sn; - - entity->common.next_nr_pdcp_tx_sn++; - if (entity->common.next_nr_pdcp_tx_sn > entity->common.maximum_nr_pdcp_sn) { - entity->common.next_nr_pdcp_tx_sn = 0; - entity->common.tx_hfn++; - } - - buf[0] = 0x80 | ((sn >> 16) & 0x3); - buf[1] = (sn >> 8) & 0xff; - buf[2] = sn & 0xff; - memcpy(buf+3, buffer, size); - - entity->common.deliver_pdu(entity->common.deliver_pdu_data, - (nr_pdcp_entity_t *)entity, buf, size+3, sdu_id); -} - -void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *key) -{ - /* nothing to do */ -} - -void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity) -{ - nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; - free(entity); -} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c new file mode 100644 index 0000000000..5553662ac5 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c @@ -0,0 +1,81 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_pdcp_integrity_nia2.h" + +#include +#include +#include +#include + +void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key) +{ + CMAC_CTX *ctx; + + ctx = CMAC_CTX_new(); + if (ctx == NULL) abort(); + + CMAC_Init(ctx, integrity_key, 16, EVP_aes_128_cbc(), NULL); + + return ctx; +} + +static void compute_t(unsigned char *t, uint32_t count, int bearer, + int direction) +{ + t[0] = (count >> 24) & 255; + t[1] = (count >> 16) & 255; + t[2] = (count >> 8) & 255; + t[3] = (count ) & 255; + t[4] = (bearer << 3) | (direction << 2); + memset(&t[5], 0, 8-5); +} + +void nr_pdcp_integrity_nia2_integrity(void *integrity_context, + unsigned char *out, + unsigned char *buffer, int length, + int bearer, int count, int direction) +{ + CMAC_CTX *ctx = integrity_context; + unsigned char t[8]; + unsigned char mac[16]; + size_t maclen; + + /* see 33.401 B.2.3 for the input to 128-EIA2 + * (which is identical to 128-NIA2, see 33.501 D.3.1.3) */ + compute_t(t, count, bearer, direction); + + CMAC_Update(ctx, t, 8); + CMAC_Update(ctx, buffer, length); + CMAC_Final(ctx, mac, &maclen); + + /* AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of + * 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant + * bit first (so seems to say 33.401 B.2.3) + */ + memcpy(out, mac, 4); +} + +void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context) +{ + CMAC_CTX *ctx = integrity_context; + CMAC_CTX_free(ctx); +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h similarity index 58% rename from openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h rename to openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h index d7c42e6a62..9593a2825c 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h @@ -19,23 +19,16 @@ * contact@openairinterface.org */ -#ifndef _NR_PDCP_ENTITY_DRB_AM_H_ -#define _NR_PDCP_ENTITY_DRB_AM_H_ +#ifndef _NR_PDCP_INTEGRITY_NIA2_H_ +#define _NR_PDCP_INTEGRITY_NIA2_H_ -#include "nr_pdcp_entity.h" +void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key); -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_integrity_nia2_integrity(void *integrity_context, + unsigned char *out, + unsigned char *buffer, int length, + int bearer, int count, int direction); -void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size); -void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *entity, char *buffer, int size, - int sdu_id); -void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *entity, char *key); -void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *entity); +void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context); -#endif /* _NR_PDCP_ENTITY_DRB_AM_H_ */ +#endif /* _NR_PDCP_INTEGRITY_NIA2_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index c0000d92a1..f499ca2843 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -24,6 +24,7 @@ #endif #include "asn1_utils.h" #include "nr_pdcp_ue_manager.h" +#include "nr_pdcp_timer_thread.h" #include "NR_RadioBearerConfig.h" #include "NR_RLC-BearerConfig.h" #include "NR_RLC-Config.h" @@ -42,6 +43,11 @@ static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager; +/* TODO: handle time a bit more properly */ +static uint64_t nr_pdcp_current_time; +static int nr_pdcp_current_time_last_frame; +static int nr_pdcp_current_time_last_subframe; + /* necessary globals for OAI, not used internally */ hash_table_t *pdcp_coll_p; static uint64_t pdcp_optmask; @@ -340,6 +346,8 @@ void pdcp_layer_init(void) nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1); init_nr_rlc_data_req_queue(); + + nr_pdcp_init_timer_thread(nr_pdcp_ue_manager); } #include "nfapi/oai_integration/vendor_ext.h" @@ -592,7 +600,11 @@ static void add_srb(int rnti, struct NR_SRB_ToAddMod *s) TODO; } -static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) +static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; @@ -622,8 +634,11 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) 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, - sn_size_dl, t_reordering, discard_timer); + pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id, + deliver_sdu_drb, ue, deliver_pdu_drb, ue, + sn_size_dl, t_reordering, discard_timer, + ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); @@ -631,16 +646,23 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config) +static void add_drb(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, + NR_RLC_Config_t *rlc_Config, + int ciphering_algorithm, + int integrity_algorithm, + unsigned char *ciphering_key, + unsigned char *integrity_key) { switch (rlc_Config->present) { case NR_RLC_Config_PR_am: - add_drb_am(rnti, s); + add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); break; case NR_RLC_Config_PR_um_Bi_Directional: //add_drb_um(rnti, s); /* hack */ - add_drb_am(rnti, s); + add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm, + ciphering_key, integrity_key); break; default: LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n", @@ -658,7 +680,8 @@ boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -677,7 +700,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( //srb2add_list == NULL || //drb2add_list != NULL || drb2release_list != NULL || - security_modeP != 255 || + //security_modeP != 255 || //kRRCenc != NULL || //kRRCint != NULL || //kUPenc != NULL || @@ -694,7 +717,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req( if (drb2add_list != NULL) { for (i = 0; i < drb2add_list->list.count; i++) { - add_drb(rnti, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config); + add_drb(ctxt_pP->enb_flag, rnti, drb2add_list->list.array[i], + rlc_bearer2add_list->list.array[i]->rlc_Config, + security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, + kUPenc, kUPint); } } @@ -706,6 +732,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( free(kRRCenc); free(kRRCint); free(kUPenc); + free(kUPint); return 0; } @@ -750,7 +777,7 @@ void nr_DRB_preconfiguration(uint16_t crnti) drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb)); drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer)); - *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_ms30; + *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_infinity; drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL)); *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len12bits; drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL)); @@ -806,6 +833,7 @@ void nr_DRB_preconfiguration(uint16_t crnti) NULL, NULL, NULL, + NULL, Rlc_Bearer_ToAdd_list); nr_rrc_rlc_config_asn1_req (&ctxt, @@ -957,3 +985,14 @@ void pdcp_mbms_run ( const protocol_ctxt_t *const ctxt_pP){ /* nothing to do */ } + +void nr_pdcp_tick(int frame, int subframe) +{ + if (frame != nr_pdcp_current_time_last_frame || + subframe != nr_pdcp_current_time_last_subframe) { + nr_pdcp_current_time_last_frame = frame; + nr_pdcp_current_time_last_subframe = subframe; + nr_pdcp_current_time++; + nr_pdcp_wakeup_timer_thread(nr_pdcp_current_time); + } +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c new file mode 100644 index 0000000000..47d95156e3 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c @@ -0,0 +1,78 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_pdcp_sdu.h" + +#include +#include + +nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size) +{ + nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t)); + if (ret == NULL) + exit(1); + ret->count = count; + ret->buffer = malloc(size); + if (ret->buffer == NULL) + exit(1); + memcpy(ret->buffer, buffer, size); + ret->size = size; + return ret; +} + +nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu) +{ + nr_pdcp_sdu_t head; + nr_pdcp_sdu_t *cur; + nr_pdcp_sdu_t *prev; + + head.next = l; + cur = l; + prev = &head; + + /* order is by 'count' */ + while (cur != NULL) { + /* check if 'sdu' is before 'cur' in the list */ + if (sdu->count < cur->count) + break; + prev = cur; + cur = cur->next; + } + prev->next = sdu; + sdu->next = cur; + return head.next; +} + +int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count) +{ + while (l != NULL) { + if (l->count == count) + return 1; + l = l->next; + } + return 0; +} + +void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu) +{ + free(sdu->buffer); + free(sdu); +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h new file mode 100644 index 0000000000..3d4e50a4ce --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h @@ -0,0 +1,39 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_PDCP_SDU_H_ +#define _NR_PDCP_SDU_H_ + +#include + +typedef struct nr_pdcp_sdu_t { + uint32_t count; + char *buffer; + int size; + struct nr_pdcp_sdu_t *next; +} nr_pdcp_sdu_t; + +nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size); +nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu); +int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count); +void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu); + +#endif /* _NR_PDCP_SDU_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c new file mode 100644 index 0000000000..fc07f661dd --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.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 + */ + +#include "nr_pdcp_security_nea2.h" + +#include +#include +#include +#include +#include + +void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key) +{ + void *ctx = calloc(1, nettle_aes128.context_size); + if (ctx == NULL) exit(1); + +#if NETTLE_VERSION_MAJOR < 3 + nettle_aes128.set_encrypt_key(ctx, 16, ciphering_key); +#else + nettle_aes128.set_encrypt_key(ctx, ciphering_key); +#endif + + return ctx; +} + +void nr_pdcp_security_nea2_cipher(void *security_context, + unsigned char *buffer, int length, + int bearer, int count, int direction) +{ + unsigned char t[16]; + + t[0] = (count >> 24) & 255; + t[1] = (count >> 16) & 255; + t[2] = (count >> 8) & 255; + t[3] = (count ) & 255; + t[4] = ((bearer-1) << 3) | (direction << 2); + memset(&t[5], 0, 16-5); + + nettle_ctr_crypt(security_context, nettle_aes128.encrypt, + nettle_aes128.block_size, t, + length, buffer, buffer); +} + +void nr_pdcp_security_nea2_free_security(void *security_context) +{ + free(security_context); +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h new file mode 100644 index 0000000000..c3667c93d4 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h @@ -0,0 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_PDCP_SECURITY_NEA2_H_ +#define _NR_PDCP_SECURITY_NEA2_H_ + +void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key); + +void nr_pdcp_security_nea2_cipher(void *security_context, + unsigned char *buffer, int length, + int bearer, int count, int direction); + +void nr_pdcp_security_nea2_free_security(void *security_context); + +#endif /* _NR_PDCP_SECURITY_NEA2_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c new file mode 100644 index 0000000000..36e9b16024 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c @@ -0,0 +1,87 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_pdcp_timer_thread.h" + +#include +#include +#include + +#include "LOG/log.h" + +static pthread_mutex_t timer_thread_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t timer_thread_cond = PTHREAD_COND_INITIALIZER; +static volatile uint64_t timer_thread_curtime = 0; + +static void *nr_pdcp_timer_thread(void *_nr_pdcp_ue_manager) +{ + nr_pdcp_ue_manager_t *nr_pdcp_ue_manager = (nr_pdcp_ue_manager_t *)_nr_pdcp_ue_manager; + nr_pdcp_ue_t **ue_list; + int ue_count; + int i; + int j; + uint64_t curtime = 0; + + while (1) { + if (pthread_mutex_lock(&timer_thread_mutex) != 0) abort(); + while (curtime == timer_thread_curtime) + if (pthread_cond_wait(&timer_thread_cond, &timer_thread_mutex) != 0) abort(); + curtime = timer_thread_curtime; + if (pthread_mutex_unlock(&timer_thread_mutex) != 0) abort(); + + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + + ue_list = nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager); + ue_count = nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager); + for (i = 0; i < ue_count; i++) { + for (j = 0; j < 2; j++) { + if (ue_list[i]->srb[j] != NULL) + ue_list[i]->srb[j]->set_time(ue_list[i]->srb[j], curtime); + } + for (j = 0; j < 5; j++) { + if (ue_list[i]->drb[j] != NULL) + ue_list[i]->drb[j]->set_time(ue_list[i]->drb[j], curtime); + } + } + + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + } + + return NULL; +} + +void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager) +{ + pthread_t t; + + if (pthread_create(&t, NULL, nr_pdcp_timer_thread, nr_pdcp_ue_manager) != 0) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +void nr_pdcp_wakeup_timer_thread(uint64_t time) +{ + if (pthread_mutex_lock(&timer_thread_mutex)) abort(); + timer_thread_curtime = time; + if (pthread_cond_broadcast(&timer_thread_cond)) abort(); + if (pthread_mutex_unlock(&timer_thread_mutex)) abort(); +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h new file mode 100644 index 0000000000..db8282f940 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h @@ -0,0 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_PDCP_TIMER_THREAD_H_ +#define _NR_PDCP_TIMER_THREAD_H_ + +#include "nr_pdcp_ue_manager.h" + +#include + +void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager); +void nr_pdcp_wakeup_timer_thread(uint64_t time); + +#endif /* _NR_PDCP_TIMER_THREAD_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c index ca51da3d5f..f89a18f94e 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c @@ -189,6 +189,20 @@ void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id, nr_pdcp_entity ue->drb[drb_id] = entity; } +/* must be called with lock acquired */ +nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m) +{ + nr_pdcp_ue_manager_internal_t *m = _m; + return m->ue_list; +} + +/* must be called with lock acquired */ +int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m) +{ + nr_pdcp_ue_manager_internal_t *m = _m; + return m->ue_count; +} + int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *_m) { nr_pdcp_ue_manager_internal_t *m = _m; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h index 0de2f024b3..3329f856b7 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h @@ -46,6 +46,9 @@ void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *m); nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *m, int rnti); void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *m, int rnti); +nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m); +int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m); + /***********************************************************************/ /* ue functions */ /***********************************************************************/ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index 1d4efc1e26..000c764e8f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -650,7 +650,7 @@ control: control_decoder = decoder; control_e1 = e1; while (control_e1) { - nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder); /* NACK_SN */ + nack_sn = nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder); control_e1 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); control_e2 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); control_e3 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); @@ -660,17 +660,36 @@ control: } else { nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); } + /* check range and so_start/so_end consistency */ if (control_e2) { - nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOstart */ - nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOend */ + so_start = nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); + so_end = nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); + } else { + so_start = 0; + so_end = 0xffff; } if (control_e3) { - nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder); /* NACK range */ + range = nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder); + } else { + range = 1; + } + if (range < 1) { + LOG_E(RLC, "%s:%d:%s: error, bad 'range' in RLC NACK (sn %d)\n", + __FILE__, __LINE__, __FUNCTION__, nack_sn); + goto err; + } + /* so_start can be > so_end if more than one range; they don't refer + * to the same PDU then + */ + if (range == 1 && so_end < so_start) { + LOG_E(RLC, "%s:%d:%s: error, bad so start/end (sn %d)\n", + __FILE__, __LINE__, __FUNCTION__, nack_sn); + goto err; } } /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is - * received for the SN 'poll_sn' + * received for the SN 'poll_sn' - check ACK case (NACK done below) */ if (sn_compare_tx(entity, entity->poll_sn, ack_sn) < 0) entity->t_poll_retransmit_start = 0; @@ -697,28 +716,22 @@ control: if (e2) { so_start = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); so_end = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); - if (so_end < so_start) { - LOG_W(RLC, "%s:%d:%s: warning, bad so start/end, NACK the whole PDU (sn %d)\n", - __FILE__, __LINE__, __FUNCTION__, nack_sn); - so_start = 0; - so_end = -1; - } - /* special value 0xffff indicates 'all bytes to the end' */ - if (so_end == 0xffff) - so_end = -1; } else { so_start = 0; - so_end = -1; + so_end = 0xffff; } if (e3) { range = nr_rlc_pdu_decoder_get_bits(&decoder, 8); R(decoder); } else { range = 1; } + /* special value 0xffff indicates 'all bytes to the end' */ + if (so_end == 0xffff) + so_end = -1; process_received_nack(entity, nack_sn, so_start, so_end, range, sn_set); /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is - * received for the SN 'poll_sn' + * received for the SN 'poll_sn' - check NACK case (ACK done above) */ if (sn_compare_tx(entity, nack_sn, entity->poll_sn) <= 0 && sn_compare_tx(entity, entity->poll_sn, (nack_sn + range) % entity->sn_modulus) < 0) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 9c139624eb..2eb2bae968 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -250,7 +250,8 @@ 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); + if (!(frameP%128)) //to supress this warning message + 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; } diff --git a/openair2/LAYER2/nr_rlc/tests/run_tests.sh b/openair2/LAYER2/nr_rlc/tests/run_tests.sh index bf1b343d7e..a98f6b5d0f 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=14 +test_count=15 for i in `seq $test_count` do diff --git a/openair2/LAYER2/nr_rlc/tests/test15.h b/openair2/LAYER2/nr_rlc/tests/test15.h new file mode 100644 index 0000000000..8ce9f97896 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test15.h @@ -0,0 +1,19 @@ +/* + * am test (SN field size 18): + * test "range" in NACK, generate a case where so_start > so_end + * (so so_start and so_end are not from the same PDU) + */ + +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_PDU_SIZE, 40, + UE_PDU_SIZE, 80, + GNB_SDU, 0, 50, + GNB_SDU, 1, 50, + GNB_SDU, 2, 50, +TIME, 2, + UE_RECV_FAILS, 1, +TIME, 4, + UE_RECV_FAILS, 0, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test15.txt.gz b/openair2/LAYER2/nr_rlc/tests/test15.txt.gz new file mode 100644 index 0000000000..e615a59a5f Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test15.txt.gz differ diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index b5cda6ecd6..5b5f3e6b3c 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -36,13 +36,13 @@ #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "common/ran_context.h" #include "executables/softmodem-common.h" +#include "nfapi/oai_integration/vendor_ext.h" #define MAX_IF_MODULES 100 //#define UL_HARQ_PRINT NR_IF_Module_t *if_inst[MAX_IF_MODULES]; NR_Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs]; - extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind); @@ -95,6 +95,7 @@ void handle_nr_uci(NR_UL_IND_t *UL_info) handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu); break; } + case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { 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); @@ -104,6 +105,7 @@ void handle_nr_uci(NR_UL_IND_t *UL_info) } 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; @@ -184,7 +186,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { module_id,CC_id, UL_info->rach_ind.number_of_pdus, UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs); - if (nfapi_mode != 1) { + if (NFAPI_MODE != NFAPI_MODE_PNF) { if (ifi->CC_mask==0) { ifi->current_frame = UL_info->frame; ifi->current_slot = UL_info->slot; @@ -203,7 +205,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { mac->UL_dci_req[CC_id].numPdus = 0; handle_nr_ulsch(UL_info); - if (nfapi_mode != 1) { + if (NFAPI_MODE != NFAPI_MODE_PNF) { if (ifi->CC_mask == ((1<scc, ul_info->slot_tx) && get_softmodem_params()->do_ra) + if (is_nr_UL_slot(mac->scc, ul_info->slot_tx, mac->frame_type) && get_softmodem_params()->do_ra) nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id); switch(ret){ diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index b4a7f8c6e7..21740016b1 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -30,6 +30,10 @@ #include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" #include "common/config/config_load_configmodule.h" #include "common/config/config_userapi.h" +#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" +#include "openair1/PHY/defs_gNB.h" +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" +#include "openair1/PHY/LTE_TRANSPORT/transport_common.h" extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void configure_nfapi_pnf(char *vnf_ip_addr, diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h index 91dc7aafd4..2a34971c23 100644 --- a/openair2/RRC/LTE/defs_NB_IoT.h +++ b/openair2/RRC/LTE/defs_NB_IoT.h @@ -148,7 +148,7 @@ typedef struct UE_RRC_INFO_NB_IoT_s { //Measurement Report not supported in NB-IoT #define PAYLOAD_SIZE_MAX 1024 -#define RRC_BUF_SIZE 255 +#define RRC_BUF_SIZE 8192 #define UNDEF_SECURITY_MODE 0xff #define NO_SECURITY_MODE 0x20 diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 7602e9ca64..6615541662 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -67,6 +67,8 @@ #define MAX_NUM_NEIGH_CELLs 6 /* maximum neighbouring cells number */ +#define MAX_NUM_GNB_CELLs 1 /* maximum gNB cells number */ + #define UE_STATE_NOTIFICATION_INTERVAL 50 #define IPV4_ADDR "%u.%u.%u.%u" @@ -327,7 +329,7 @@ typedef enum SL_TRIGGER_e { #define MAX_MEAS_ID 6 #define PAYLOAD_SIZE_MAX 1024 -#define RRC_BUF_SIZE 255 +#define RRC_BUF_SIZE 8192 #define UNDEF_SECURITY_MODE 0xff #define NO_SECURITY_MODE 0x20 @@ -546,6 +548,13 @@ typedef struct rrc_gummei_s { uint16_t mme_group_id; } rrc_gummei_t; +typedef struct { + uint16_t ciphering_algorithms; + uint16_t integrity_algorithms; + uint16_t sk_counter; + uint8_t kgNB[32]; +} lte_rrc_nr_security_t; + typedef struct eNB_RRC_UE_s { uint8_t primaryCC_id; LTE_SCellToAddMod_r10_t sCell_config[2]; @@ -615,6 +624,9 @@ typedef struct eNB_RRC_UE_s { security_capabilities_t security_capabilities; + /* security capabilities and settings for an UE in ENDC mode */ + lte_rrc_nr_security_t nr_security; + int next_hop_chain_count; uint8_t next_security_key[SECURITY_KEY_LENGTH]; @@ -794,8 +806,13 @@ typedef struct eNB_RRC_INST_s { int num_neigh_cells_cc[MAX_NUM_CCs]; uint32_t neigh_cells_id[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs]; + // gNB cells connected to this eNB + int num_gnb_cells; + int num_gnb_cells_cc[MAX_NUM_GNB_CELLs]; + uint32_t gnb_cells_id[MAX_NUM_GNB_CELLs][MAX_NUM_CCs]; + // Nr scc freq band and SSB absolute frequency - uint32_t nr_neigh_freq_band[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs]; + uint32_t nr_gnb_freq_band[MAX_NUM_GNB_CELLs][MAX_NUM_CCs]; int nr_scg_ssb_freq; // other RAN parameters diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index df5495ca53..e6cbcc5720 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -1284,7 +1284,7 @@ rrc_eNB_generate_UECapabilityEnquiry( 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)); int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0]; - uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0]; + uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0]; size = do_UECapabilityEnquiry( ctxt_pP, buffer, @@ -1334,7 +1334,7 @@ rrc_eNB_generate_NR_UECapabilityEnquiry( 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)); int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0]; - uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0]; + uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_gnb_freq_band[0][0]; size = do_NR_UECapabilityEnquiry( ctxt_pP, buffer, @@ -4427,69 +4427,11 @@ static int encode_CG_ConfigInfo( struct NR_RadioBearerConfig *rb_config = NULL; asn_enc_rval_t enc_rval; int RRC_OK = 1; - int index = 0; char temp_buff[ASN_MAX_ENCODE_SIZE]; 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"); - - if(ue_context_pP->ue_context.DRB_configList->list.count != 0) { - rb_config->drb_ToAddModList = calloc(1,sizeof(struct NR_DRB_ToAddModList )); - AssertFatal(rb_config->drb_ToAddModList != NULL,"failed to allocated memory for drbtoaddmodlist"); - rb_config->drb_ToAddModList->list.count = NUMBEROF_DRBS_TOBE_ADDED; - rb_config->drb_ToAddModList->list.array - = calloc(NUMBEROF_DRBS_TOBE_ADDED, sizeof(struct NR_DRB_ToAddMod *)); - AssertFatal( rb_config->drb_ToAddModList->list.array != NULL, - "falied to allocate memory for list.array"); - - for(index = 0; index < NUMBEROF_DRBS_TOBE_ADDED; index++) { - rb_config->drb_ToAddModList->list.array[index] - = calloc(1,sizeof(struct NR_DRB_ToAddMod)); - AssertFatal(rb_config->drb_ToAddModList->list.array[index] != NULL, - "failed to allocate memory for drb_toaddmod"); - rb_config->drb_ToAddModList->list.array[index]->drb_Identity - = ue_context_pP->ue_context.DRB_configList->list.array[index]->drb_Identity; - - if(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity) { - rb_config->drb_ToAddModList->list.array[index]->cnAssociation - = calloc(1,sizeof(struct NR_DRB_ToAddMod__cnAssociation)); - AssertFatal(rb_config->drb_ToAddModList->list.array[index]->cnAssociation != NULL, - "failed to allocate memory cnAssociation"); - rb_config->drb_ToAddModList->list.array[index]->cnAssociation->present - = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; - rb_config->drb_ToAddModList->list.array[index]->cnAssociation->choice.eps_BearerIdentity - = *(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity); - } - - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config = calloc(1,sizeof(struct NR_PDCP_Config)); - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb = calloc(1,sizeof(struct NR_PDCP_Config__drb)); - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer - = *(ue_context_pP->ue_context.DRB_configList->list.array[index]->pdcp_Config->discardTimer); - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL - = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL - = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.present - = NR_PDCP_Config__drb__headerCompression_PR_notUsed; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.choice.notUsed = 0; - rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering = calloc(1,sizeof(long)); - *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering - = NR_PDCP_Config__t_Reordering_ms0; - } - - rb_config->securityConfig = calloc(1,sizeof(struct NR_SecurityConfig )); - rb_config->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(struct NR_SecurityAlgorithmConfig)); - rb_config->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; - rb_config->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm = NULL; - rb_config->securityConfig->keyToUse = calloc(1,sizeof(long)); - *rb_config->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; - } cg_configinfo = calloc(1,sizeof(struct NR_CG_ConfigInfo)); AssertFatal(cg_configinfo != NULL,"failed to allocate memory for cg_configinfo"); @@ -4549,15 +4491,6 @@ static int encode_CG_ConfigInfo( (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-> - mcg_RB_Config != NULL, "failed to allocate memory for mcg_rb_config"); - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RadioBearerConfig,NULL,(void *)rb_config,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->mcg_RB_Config, - (const char *)temp_buff, (enc_rval.encoded+7)>>3); // this xer_fprint can be enabled for additional debugging messages // xer_fprint(stdout,&asn_DEF_NR_CG_ConfigInfo,(void *)cg_configinfo); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_ConfigInfo,NULL,(void *)cg_configinfo, @@ -4666,11 +4599,20 @@ rrc_eNB_process_MeasurementReport( 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; + + X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms = ue_context_pP->ue_context.nr_security.ciphering_algorithms; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms = ue_context_pP->ue_context.nr_security.integrity_algorithms; + + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ue_context_pP->ue_context.nr_security.kgNB, 32); + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size); X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId; + //For the moment we have a single E-RAB which will be the one to be added to the gNB //Not sure how to select bearers to be added if there are multiple. X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1; @@ -7647,8 +7589,8 @@ is_en_dc_supported( ) //----------------------------------------------------------------------------- { - /* to be refined - check that the eNB is connected to a gNB, check that - * the bands supported by the UE include the band of the gNB + /* to be refined - check that the bands supported by the UE include + * the band of the gNB */ #define NCE nonCriticalExtension return c != NULL @@ -8348,8 +8290,13 @@ rrc_eNB_decode_dcch( ue_context_p->ue_context.UE_Capability = 0; } - if (dec_rval.code == RC_OK) - ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability); + if (dec_rval.code == RC_OK) { + /* do NR only if at least one gNB connected */ + if (RC.rrc[ctxt_pP->module_id]->num_gnb_cells != 0) + ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability); + else + ue_context_p->ue_context.does_nr = 0; + } if (EPC_MODE_ENABLED) { rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP, @@ -9088,22 +9035,22 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { } void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m) { - if (RC.rrc[mod_id]->num_neigh_cells > MAX_NUM_NEIGH_CELLs) { - LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n"); + if (RC.rrc[mod_id]->num_gnb_cells >= MAX_NUM_GNB_CELLs) { + LOG_E(RRC, "Error: number of gNB cells is exceeded\n"); return; } if (m->num_cc > MAX_NUM_CCs) { - LOG_E(RRC, "Error: number of neighbouring cells carriers is exceeded \n"); + LOG_E(RRC, "Error: number of gNB cells carriers is exceeded \n"); return; } - RC.rrc[mod_id]->num_neigh_cells++; - RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc; + RC.rrc[mod_id]->num_gnb_cells++; + RC.rrc[mod_id]->num_gnb_cells_cc[RC.rrc[mod_id]->num_gnb_cells-1] = m->num_cc; for (int i=0; inum_cc; i++) { - RC.rrc[mod_id]->neigh_cells_id[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->Nid_cell[i]; - RC.rrc[mod_id]->nr_neigh_freq_band[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->servedNrCell_band[i]; + RC.rrc[mod_id]->gnb_cells_id[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->Nid_cell[i]; + RC.rrc[mod_id]->nr_gnb_freq_band[RC.rrc[mod_id]->num_gnb_cells-1][i] = m->servedNrCell_band[i]; } } diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 741aaeb38b..f64a109f75 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -783,21 +783,37 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei; if (r_mme->plmn_Identity != NULL) { - if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) { - /* Use first indicated PLMN MCC if it is defined */ - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity]; + if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count == 3)) + { + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = (*r_mme->plmn_Identity->mcc->list.array[0] & 0xf) * 100 + + (*r_mme->plmn_Identity->mcc->list.array[1] & 0xf) * 10 + + (*r_mme->plmn_Identity->mcc->list.array[2] & 0xf); LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", ctxt_pP->module_id, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc, ue_context_pP->ue_context.rnti); } - - if (r_mme->plmn_Identity->mnc.list.count > 0) { - /* Use first indicated PLMN MNC if it is defined */ - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity]; - LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", + if(r_mme->plmn_Identity->mnc.list.count == 3) + { + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 100 + + (*r_mme->plmn_Identity->mnc.list.array[1] & 0xf) * 10 + + (*r_mme->plmn_Identity->mnc.list.array[2] & 0xf); + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 3; + LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n", ctxt_pP->module_id, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len, + ue_context_pP->ue_context.rnti); + } + else if(r_mme->plmn_Identity->mnc.list.count == 2) + { + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 10 + + (*r_mme->plmn_Identity->mnc.list.array[1] & 0xf); + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 2; + LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n", + ctxt_pP->module_id, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len, ue_context_pP->ue_context.rnti); } } else { // end if plmn_Identity != NULL @@ -1046,6 +1062,15 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char } } + ue_context_p->ue_context.nr_security.ciphering_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.encryption_algorithms; + ue_context_p->ue_context.nr_security.integrity_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.integrity_algorithms; + /* let's initialize sk_counter to 0 */ + ue_context_p->ue_context.nr_security.sk_counter = 0; + /* let's compute kgNB */ + derive_skgNB(ue_context_p->ue_context.kenb, + ue_context_p->ue_context.nr_security.sk_counter, + ue_context_p->ue_context.nr_security.kgNB); + // 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 == RRC_RECONFIGURED) { LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause); diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index eb43eeb5f2..58c595a3d0 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -303,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 82855365c8..6c28beec34 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -561,14 +561,14 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, 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. - */ + /* + 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; diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index c53d44983c..e0b04a6976 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -127,7 +127,7 @@ typedef enum UE_STATE_NR_e { #define MAX_MEAS_ID 6 #define PAYLOAD_SIZE_MAX 1024 -#define RRC_BUF_SIZE 255 +#define RRC_BUF_SIZE 8192 #define UNDEF_SECURITY_MODE 0xff #define NO_SECURITY_MODE 0x20 @@ -431,6 +431,7 @@ typedef struct { NR_BCCH_BCH_Message_t mib; int ssb_SubcarrierOffset; int pdsch_AntennaPorts; + int pusch_AntennaPorts; int pusch_TargetSNRx10; int pucch_TargetSNRx10; NR_BCCH_DL_SCH_Message_t *siblock1; @@ -447,6 +448,15 @@ typedef struct { //--------------------------------------------------- +typedef struct { + /* nea0 = 0, nea1 = 1, ... */ + int ciphering_algorithms[4]; + int ciphering_algorithms_count; + + /* nia0 = 0, nia1 = 1, ... */ + int integrity_algorithms[4]; + int integrity_algorithms_count; +} nr_security_configuration_t; //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -479,6 +489,8 @@ typedef struct gNB_RRC_INST_s { int srb1_timer_status_prohibit; int srs_enable[MAX_NUM_CCs]; + // security configuration (preferred algorithms) + nr_security_configuration_t security; } gNB_RRC_INST; #include "nr_rrc_proto.h" //should be put here otherwise compilation error diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 9b7d734e2c..5aafbaee4c 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -39,6 +39,7 @@ #include "LTE_UE-CapabilityRAT-ContainerList.h" #include "NR_CG-Config.h" #include "NR_CG-ConfigInfo.h" +#include "NR_SecurityConfig.h" int rrc_init_nr_global_param(void); @@ -78,19 +79,24 @@ void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellC void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0); void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon, - NR_CellGroupConfig_t *secondaryCellGroup, - int scg_id, - int servCellIndex, - int n_physical_antenna_ports, - int initial_csi_index); + NR_ServingCellConfig_t *servingcellconfigdedicated, + NR_CellGroupConfig_t *secondaryCellGroup, + int scg_id, + int servCellIndex, + int n_physical_antenna_ports, + int initial_csi_index); void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon, - NR_RRCReconfiguration_IEs_t *reconfig, - NR_CellGroupConfig_t *secondaryCellGroup, - int n_physical_antenna_ports, - int initial_csi_index); + NR_ServingCellConfig_t *servingcellconfigdedicated, + NR_RRCReconfiguration_IEs_t *reconfig, + NR_CellGroupConfig_t *secondaryCellGroup, + int n_physical_antenna_ports, + int initial_csi_index); -void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig); +void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig, + int eps_bearer_id, int rb_id, + e_NR_CipheringAlgorithm ciphering_algorithm, + e_NR_SecurityConfig__keyToUse key_to_use); int generate_CG_Config(gNB_RRC_INST *rrc, NR_CG_Config_t *cg_Config, diff --git a/openair2/RRC/NR/nr_rrc_types.h b/openair2/RRC/NR/nr_rrc_types.h index 02495591a9..61f90e3572 100644 --- a/openair2/RRC/NR/nr_rrc_types.h +++ b/openair2/RRC/NR/nr_rrc_types.h @@ -32,11 +32,11 @@ #define RRC_TYPES_NR_H_ typedef enum Rrc_State_NR_e { - RRC_STATE_INACTIVE_NR=0, - RRC_STATE_IDLE_NR, + RRC_STATE_IDLE_NR=0, + RRC_STATE_INACTIVE_NR, RRC_STATE_CONNECTED_NR, - RRC_STATE_FIRST_NR = RRC_STATE_INACTIVE_NR, + RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR, RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR, } Rrc_State_NR_t; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index abf85a805b..9bea266ffd 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -103,7 +103,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -223,6 +224,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration rrc_mac_config_req_gNB(rrc->module_id, rrc->carrier.ssb_SubcarrierOffset, rrc->carrier.pdsch_AntennaPorts, + rrc->carrier.pusch_AntennaPorts, rrc->carrier.pusch_TargetSNRx10, rrc->carrier.pucch_TargetSNRx10, (NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon, @@ -276,6 +278,8 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration parse_CG_ConfigInfo(rrc,CG_ConfigInfo,NULL); } else { struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc); + ue_context_p->ue_context.spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig)); + ue_context_p->ue_context.spCellConfig->spCellConfigDedicated = configuration->scd; LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p); rrc_add_nsa_user(rrc,ue_context_p,NULL); } @@ -306,6 +310,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu rrc->carrier.servingcellconfigcommon = configuration->scc; rrc->carrier.ssb_SubcarrierOffset = configuration->ssb_SubcarrierOffset; rrc->carrier.pdsch_AntennaPorts = configuration->pdsch_AntennaPorts; + rrc->carrier.pusch_AntennaPorts = configuration->pusch_AntennaPorts; rrc->carrier.pusch_TargetSNRx10 = configuration->pusch_TargetSNRx10; rrc->carrier.pucch_TargetSNRx10 = configuration->pucch_TargetSNRx10; /// System Information INIT @@ -459,6 +464,7 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( 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_AntennaPorts, rrc_instance_p->carrier.pusch_TargetSNRx10, rrc_instance_p->carrier.pucch_TargetSNRx10, (NR_ServingCellConfigCommon_t *)rrc_instance_p->carrier.servingcellconfigcommon, @@ -630,7 +636,7 @@ rrc_gNB_generate_defaultRRCReconfiguration( 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->discardTimer = NR_PDCP_Config__drb__discardTimer_infinity; 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)); @@ -887,6 +893,7 @@ rrc_gNB_process_RRCReconfigurationComplete( kUPenc, NULL, NULL, + NULL, NULL); /* Refresh SRBs/DRBs */ nr_rrc_rlc_config_asn1_req(ctxt_pP, @@ -1702,6 +1709,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, // NULL, // NULL, // NULL, + // NULL, // NULL); // if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index fec92ca0aa..2336c758fc 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -40,6 +40,7 @@ #include "executables/softmodem-common.h" #include #include +#include "UTIL/OSA/osa_defs.h" extern boolean_t nr_rrc_pdcp_config_asn1_req( const protocol_ctxt_t *const ctxt_pP, @@ -49,7 +50,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req( const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, - uint8_t *const kUPenc + uint8_t *const kUPenc, + uint8_t *const kUPint #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -116,28 +118,14 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL // dump ue_capabilities - if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_nr != NULL) ) { + if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_nr != NULL ) { xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr); } - if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_MRDC != NULL) ) { + if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_MRDC != NULL ) { xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC); } - if(cg_config_info && cg_config_info->mcg_RB_Config) { - asn_dec_rval_t dec_rval = uper_decode(NULL, - &asn_DEF_NR_RadioBearerConfig, - (void **)&ue_context_p->ue_context.rb_config, - cg_config_info->mcg_RB_Config->buf, - cg_config_info->mcg_RB_Config->size, 0, 0); - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"[InterNode] Failed to decode mcg_rb_config (%zu bits), size of OCTET_STRING %lu\n", - dec_rval.consumed, cg_config_info->mcg_RB_Config->size); - } - } - - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ue_context_p->ue_context.rb_config); rrc_add_nsa_user(rrc,ue_context_p, m); } @@ -153,6 +141,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; protocol_ctxt_t ctxt={0}; + unsigned char *kUPenc = NULL; + int i; // 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)); @@ -163,15 +153,107 @@ 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; + ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t)); 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); + fill_default_rbconfig(ue_context_p->ue_context.rb_config, + 5 /* EPS bearer ID */, + 1 /* drb ID */, + NR_CipheringAlgorithm_nea0, + NR_SecurityConfig__keyToUse_master); + } else { + /* TODO: handle more than one bearer */ + if (m == NULL) { + LOG_E(RRC, "fatal: m==NULL\n"); + exit(1); + } + if (m->nb_e_rabs_tobeadded != 1) { + LOG_E(RRC, "fatal: m->nb_e_rabs_tobeadded = %d, should be 1\n", m->nb_e_rabs_tobeadded); + exit(1); + } + + /* store security key and security capabilities */ + memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32); + ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms; + ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms; + + /* Select ciphering algorithm based on gNB configuration file and + * UE's supported algorithms. + * We take the first from the list that is supported by the UE. + * The ordering of the list comes from the configuration file. + */ + /* preset nea0 as fallback */ + ue_context_p->ue_context.ciphering_algorithm = 0; + for (i = 0; i < rrc->security.ciphering_algorithms_count; i++) { + int nea_mask[4] = { + 0, + 0x8000, /* nea1 */ + 0x4000, /* nea2 */ + 0x2000 /* nea3 */ + }; + if (rrc->security.ciphering_algorithms[i] == 0) { + /* nea0 already preselected */ + break; + } + if (ue_context_p->ue_context.security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) { + ue_context_p->ue_context.ciphering_algorithm = rrc->security.ciphering_algorithms[i]; + break; + } + } + + LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)ue_context_p->ue_context.ciphering_algorithm); + + /* integrity: no integrity protection for DRB in ENDC mode + * as written in 38.331: "If UE is connected to E-UTRA/EPC, this field + * indicates the integrity protection algorithm to be used for SRBs + * configured with NR PDCP, as specified in TS 33.501" + * So nothing for DRB. Plus a test with a COTS UE revealed that it + * did not apply integrity on the DRB. + */ + ue_context_p->ue_context.integrity_algorithm = 0; + + LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm); + + /* derive UP security key */ + unsigned char *kUPenc_kdf; + nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm, + ue_context_p->ue_context.kgnb, + &kUPenc_kdf); + /* kUPenc: last 128 bits of key derivation function which returns 256 bits */ + kUPenc = malloc(16); + if (kUPenc == NULL) exit(1); + memcpy(kUPenc, kUPenc_kdf+16, 16); + free(kUPenc_kdf); + + e_NR_CipheringAlgorithm cipher_algo; + switch (ue_context_p->ue_context.ciphering_algorithm) { + case 0: cipher_algo = NR_CipheringAlgorithm_nea0; break; + case 1: cipher_algo = NR_CipheringAlgorithm_nea1; break; + case 2: cipher_algo = NR_CipheringAlgorithm_nea2; break; + case 3: cipher_algo = NR_CipheringAlgorithm_nea3; break; + default: LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); + } + + fill_default_rbconfig(ue_context_p->ue_context.rb_config, + m->e_rabs_tobeadded[0].e_rab_id, + m->e_rabs_tobeadded[0].drb_ID, + cipher_algo, + NR_SecurityConfig__keyToUse_secondary); } - fill_default_reconfig(carrier->servingcellconfigcommon, + if (ue_context_p->ue_context.spCellConfig) { + fill_default_reconfig(carrier->servingcellconfigcommon, + ue_context_p->ue_context.spCellConfig->spCellConfigDedicated, reconfig_ies, ue_context_p->ue_context.secondaryCellGroup, carrier->pdsch_AntennaPorts, carrier->initial_csi_index[rrc->Nb_ue]); + } else { + fill_default_reconfig(carrier->servingcellconfigcommon, + NULL, + reconfig_ies, + ue_context_p->ue_context.secondaryCellGroup, + carrier->pdsch_AntennaPorts, + carrier->initial_csi_index[rrc->Nb_ue]); + } ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void *)CG_Config,0,sizeof(*CG_Config)); @@ -256,7 +338,7 @@ 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) { + } else if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) { PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id); } @@ -265,6 +347,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ rrc_mac_config_req_gNB(rrc->module_id, rrc->carrier.ssb_SubcarrierOffset, rrc->carrier.pdsch_AntennaPorts, + rrc->carrier.pusch_AntennaPorts, rrc->carrier.pusch_TargetSNRx10, rrc->carrier.pucch_TargetSNRx10, NULL, @@ -286,10 +369,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ (NR_SRB_ToAddModList_t *) NULL, ue_context_p->ue_context.rb_config->drb_ToAddModList , ue_context_p->ue_context.rb_config->drb_ToReleaseList, - 0xff, - NULL, - NULL, - NULL, + (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, + NULL, /* kRRCenc - unused */ + NULL, /* kRRCint - unused */ + kUPenc, /* kUPenc */ + NULL, /* kUPint - unused */ NULL, NULL, ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index aebdc2f1cc..8e60dafb27 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -31,6 +31,7 @@ #define RRC_GNB_NSA_C #include "NR_ServingCellConfigCommon.h" +#include "NR_ServingCellConfig.h" #include "NR_RRCReconfiguration.h" #include "NR_RRCReconfiguration-IEs.h" #include "NR_CellGroupConfig.h" @@ -135,7 +136,7 @@ void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0) { // 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->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2; ss0->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; ss0->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; @@ -143,6 +144,7 @@ void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0) { } void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon, + NR_ServingCellConfig_t *servingcellconfigdedicated, NR_CellGroupConfig_t *secondaryCellGroup, int scg_id, int servCellIndex, @@ -172,7 +174,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->cellGroupId = scg_id; NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); nr_rlc_bearer_init(RLC_BearerConfig); - if (get_softmodem_params()->do_ra) + if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) 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); @@ -240,41 +242,18 @@ 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[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 + + int n_ssb = 0; + struct NR_CFRA_SSB_Resource *ssbElem[64]; + for (int i=0;i<64;i++) { + if ((bitmap>>(63-i))&0x01){ + ssbElem[n_ssb] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem[n_ssb]->ssb = i; + ssbElem[n_ssb]->ra_PreambleIndex = 63; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[n_ssb]); + n_ssb++; + } + } 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; @@ -285,7 +264,11 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco 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 = NR_RLF_TimersAndConstants__ext1__t311_ms30000; secondaryCellGroup->spCellConfig->rlmInSyncOutOfSyncThreshold = NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated)); + if (servingcellconfigdedicated) { + secondaryCellGroup->spCellConfig->spCellConfigDedicated = servingcellconfigdedicated; + } else { + secondaryCellGroup->spCellConfig->spCellConfigDedicated = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated)); + } secondaryCellGroup->spCellConfig->spCellConfigDedicated->tdd_UL_DL_ConfigurationDedicated = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdcch_Config=NULL; @@ -311,7 +294,7 @@ 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; + n_ssb = 0; NR_TCI_State_t *tcic[64]; for (int i=0;i<64;i++) { if ((bitmap>>(63-i))&0x01){ @@ -460,9 +443,15 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco #endif secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList= NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList)); + + NR_BWP_Downlink_t *bwp = NULL; + if (servingcellconfigdedicated) { + bwp=servingcellconfigdedicated->downlinkBWP_ToAddModList->list.array[0]; + } else { + secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList)); - NR_BWP_Downlink_t *bwp=calloc(1,sizeof(*bwp)); + bwp=calloc(1,sizeof(*bwp)); + } bwp->bwp_Id=1; bwp->bwp_Common=calloc(1,sizeof(*bwp->bwp_Common)); // copy common BWP size from initial BWP except for bandwdith @@ -577,8 +566,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list,pdschi); } - bwp->bwp_Dedicated=calloc(1,sizeof(*bwp->bwp_Dedicated)); - + if (!servingcellconfigdedicated) { + bwp->bwp_Dedicated=calloc(1,sizeof(*bwp->bwp_Dedicated)); + } bwp->bwp_Dedicated->pdcch_Config=calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config)); bwp->bwp_Dedicated->pdcch_Config->present = NR_SetupRelease_PDCCH_Config_PR_setup; bwp->bwp_Dedicated->pdcch_Config->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup)); @@ -626,113 +616,30 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToReleaseList = NULL; - bwp->bwp_Dedicated->pdsch_Config = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config)); + if (!servingcellconfigdedicated) { + 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 = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup)); + } + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dataScramblingIdentityPDSCH = NULL; - 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->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type)); 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; - + if (!servingcellconfigdedicated) { + 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; - //bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList)); -#if 0 - bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList)); - - NR_TCI_State_t*tcid0=calloc(1,sizeof(*tcid0)); - tcid0->tci_StateId=0; - tcid0->qcl_Type1.cell=NULL; - tcid0->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid0->qcl_Type1.bwp_Id)); - *tcid0->qcl_Type1.bwp_Id=1; - tcid0->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; - tcid0->qcl_Type1.referenceSignal.choice.csi_rs = 2; - tcid0->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid0); - - NR_TCI_State_t*tcid1=calloc(1,sizeof(*tcid1)); - tcid1->tci_StateId=0; - tcid1->qcl_Type1.cell=NULL; - tcid1->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid1->qcl_Type1.bwp_Id)); - *tcid1->qcl_Type1.bwp_Id=1; - tcid1->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; - tcid1->qcl_Type1.referenceSignal.choice.csi_rs = 6; - tcid1->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid1); - - NR_TCI_State_t*tcid2=calloc(1,sizeof(*tcid2)); - tcid2->tci_StateId=2; - tcid2->qcl_Type1.cell=NULL; - tcid2->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid2->qcl_Type1.bwp_Id)); - *tcid2->qcl_Type1.bwp_Id=1; - tcid2->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; - tcid2->qcl_Type1.referenceSignal.choice.csi_rs = 10; - tcid2->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid2); - - NR_TCI_State_t*tcid3=calloc(1,sizeof(*tcid3)); - tcid3->tci_StateId=3; - tcid3->qcl_Type1.cell=NULL; - tcid3->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid3->qcl_Type1.bwp_Id)); - *tcid3->qcl_Type1.bwp_Id=1; - tcid3->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; - tcid3->qcl_Type1.referenceSignal.choice.csi_rs = 14; - tcid3->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid3); - - NR_TCI_State_t*tcid4=calloc(1,sizeof(*tcid4)); - tcid4->tci_StateId=4; - tcid4->qcl_Type1.cell=NULL; - tcid4->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid4->qcl_Type1.bwp_Id)); - *tcid4->qcl_Type1.bwp_Id=1; - tcid4->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; - tcid4->qcl_Type1.referenceSignal.choice.csi_rs = 18; - tcid4->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid4); - - NR_TCI_State_t*tcid5=calloc(1,sizeof(*tcid5)); - tcid5->tci_StateId=5; - tcid5->qcl_Type1.cell=NULL; - tcid5->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid5->qcl_Type1.bwp_Id)); - *tcid5->qcl_Type1.bwp_Id=1; - tcid5->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; - tcid5->qcl_Type1.referenceSignal.choice.csi_rs = 22; - tcid5->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid5); - - NR_TCI_State_t*tcid6=calloc(1,sizeof(*tcid6)); - tcid6->tci_StateId=6; - tcid6->qcl_Type1.cell=NULL; - tcid6->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid6->qcl_Type1.bwp_Id)); - *tcid6->qcl_Type1.bwp_Id=1; - tcid6->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; - tcid6->qcl_Type1.referenceSignal.choice.csi_rs = 26; - tcid6->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid6); - - NR_TCI_State_t*tcid7=calloc(1,sizeof(*tcid7)); - tcid7->tci_StateId=7; - tcid7->qcl_Type1.cell=NULL; - tcid7->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid7->qcl_Type1.bwp_Id)); - *tcid7->qcl_Type1.bwp_Id=1; - tcid7->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_csi_rs; - tcid7->qcl_Type1.referenceSignal.choice.csi_rs = 30; - tcid7->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid7); -#endif - - n_ssb = 0; NR_TCI_State_t *tcid[64]; for (int i=0;i<64;i++) { @@ -828,8 +735,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco *bwp->bwp_Dedicated->radioLinkMonitoringConfig->choice.setup->beamFailureDetectionTimer = NR_RadioLinkMonitoringConfig__beamFailureDetectionTimer_pbfd2; #endif - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list,bwp); - + if (!servingcellconfigdedicated) { + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list,bwp); + } secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id=1; @@ -837,26 +745,38 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = calloc(1, sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = 1; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig)); + + if (!servingcellconfigdedicated) { + secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig)); + } NR_BWP_UplinkDedicated_t *initialUplinkBWP = calloc(1,sizeof(*initialUplinkBWP)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP = initialUplinkBWP; initialUplinkBWP->pucch_Config = NULL; initialUplinkBWP->pusch_Config = calloc(1,sizeof(*initialUplinkBWP->pusch_Config)); initialUplinkBWP->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup; - NR_PUSCH_Config_t *pusch_Config = calloc(1,sizeof(*pusch_Config)); + NR_PUSCH_Config_t *pusch_Config = NULL; + if (servingcellconfigdedicated) { + pusch_Config = servingcellconfigdedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]->bwp_Dedicated->pusch_Config->choice.setup; + } else { + pusch_Config = calloc(1,sizeof(*pusch_Config)); + } initialUplinkBWP->pusch_Config->choice.setup = pusch_Config; pusch_Config->txConfig=calloc(1,sizeof(*pusch_Config->txConfig)); *pusch_Config->txConfig= NR_PUSCH_Config__txConfig_codebook; pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA = NULL; - pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB = calloc(1,sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB)); - pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->present = NR_SetupRelease_DMRS_UplinkConfig_PR_setup; - pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup)); + if (!servingcellconfigdedicated) { + pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB = calloc(1,sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB)); + pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->present = NR_SetupRelease_DMRS_UplinkConfig_PR_setup; + pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup)); + } NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; NR_DMRS_UplinkConfig->dmrs_Type = NULL; NR_DMRS_UplinkConfig->dmrs_AdditionalPosition = calloc(1,sizeof(*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition)); *NR_DMRS_UplinkConfig->dmrs_AdditionalPosition = NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos0; - NR_DMRS_UplinkConfig->phaseTrackingRS=NULL; + if (!servingcellconfigdedicated) { + NR_DMRS_UplinkConfig->phaseTrackingRS=NULL; + } NR_DMRS_UplinkConfig->maxLength=NULL; NR_DMRS_UplinkConfig->transformPrecodingDisabled = calloc(1,sizeof(*NR_DMRS_UplinkConfig->transformPrecodingDisabled)); NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0 = NULL; @@ -903,7 +823,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco 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. @@ -918,20 +838,20 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco if (servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder != NULL) transform_precoding = NR_PUSCH_Config__transformPrecoder_enabled; } - else + 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->sequenceGroupHopping = NULL; NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceHopping = NULL; - NR_DMRS_UplinkConfig->transformPrecodingEnabled->ext1 = NULL; + NR_DMRS_UplinkConfig->transformPrecodingEnabled->ext1 = NULL; LOG_I(RRC,"TRANSFORM PRECODING ENABLED......\n"); - + } /*----------------------------------------------------------------------------------------------------------------------------*/ @@ -992,8 +912,13 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&srs_Config->srs_ResourceToAddModList->list,srs_res0); secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList = NULL; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList)); - NR_BWP_Uplink_t *ubwp = calloc(1,sizeof(*ubwp)); + NR_BWP_Uplink_t *ubwp = NULL; + if (servingcellconfigdedicated) { + ubwp = servingcellconfigdedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]; + } else { + secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList)); + ubwp = calloc(1,sizeof(*ubwp)); + } ubwp->bwp_Id=1; ubwp->bwp_Common = calloc(1,sizeof(*ubwp->bwp_Common)); // copy bwp_Common from Initial UL BWP except for bandwidth @@ -1006,7 +931,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ubwp->bwp_Common->pusch_ConfigCommon = servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon; ubwp->bwp_Common->pucch_ConfigCommon = servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon; - ubwp->bwp_Dedicated = calloc(1,sizeof(*ubwp->bwp_Dedicated)); + if (!servingcellconfigdedicated) { + ubwp->bwp_Dedicated = calloc(1,sizeof(*ubwp->bwp_Dedicated)); + } ubwp->bwp_Dedicated->pucch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pucch_Config)); ubwp->bwp_Dedicated->pucch_Config->present = NR_SetupRelease_PUCCH_Config_PR_setup; NR_PUCCH_Config_t *pucch_Config = calloc(1,sizeof(*pucch_Config)); @@ -1136,11 +1063,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->p0_Set->list,p00); pucch_Config->pucch_PowerControl->pathlossReferenceRSs = NULL; - // copy pusch_Config from dedicated initialBWP - ubwp->bwp_Dedicated->pusch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pusch_Config)); - ubwp->bwp_Dedicated->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup; - ubwp->bwp_Dedicated->pusch_Config->choice.setup = pusch_Config; - + if (!servingcellconfigdedicated) { + // copy pusch_Config from dedicated initialBWP + ubwp->bwp_Dedicated->pusch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pusch_Config)); + ubwp->bwp_Dedicated->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup; + ubwp->bwp_Dedicated->pusch_Config->choice.setup = pusch_Config; + } ubwp->bwp_Dedicated->configuredGrantConfig = NULL; ubwp->bwp_Dedicated->srs_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->srs_Config)); ubwp->bwp_Dedicated->srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup; @@ -1148,7 +1076,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ubwp->bwp_Dedicated->beamFailureRecoveryConfig = NULL; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list,ubwp); + if (!servingcellconfigdedicated) { + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list,ubwp); + } secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = 1; @@ -1300,7 +1230,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->servingCellMO=NULL; } + void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon, + NR_ServingCellConfig_t *servingcellconfigdedicated, NR_RRCReconfiguration_IEs_t *reconfig, NR_CellGroupConfig_t *secondaryCellGroup, int n_physical_antenna_ports, @@ -1311,7 +1243,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon // radioBearerConfig reconfig->radioBearerConfig=NULL; // secondaryCellGroup - fill_default_secondaryCellGroup(servingcellconfigcommon,secondaryCellGroup,1,1,n_physical_antenna_ports,initial_csi_index); + fill_default_secondaryCellGroup(servingcellconfigcommon,servingcellconfigdedicated,secondaryCellGroup,1,1,n_physical_antenna_ports,initial_csi_index); xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); char scg_buffer[1024]; @@ -1329,7 +1261,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon reconfig->nonCriticalExtension = NULL; } -void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { +void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig, + int eps_bearer_id, int rb_id, + e_NR_CipheringAlgorithm ciphering_algorithm, + e_NR_SecurityConfig__keyToUse key_to_use) { rbconfig->srb_ToAddModList = NULL; rbconfig->srb3_ToRelease = NULL; @@ -1337,14 +1272,14 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod)); drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation)); drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; - drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5; - drb_ToAddMod->drb_Identity = 1; + drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= eps_bearer_id; + drb_ToAddMod->drb_Identity = rb_id; drb_ToAddMod->reestablishPDCP = NULL; drb_ToAddMod->recoverPDCP = NULL; drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb)); drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer)); - *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_ms30; + *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_infinity; drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL)); *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL)); @@ -1367,12 +1302,12 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig)); rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig)); - rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; + rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = ciphering_algorithm; rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL; rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse)); - *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; + *rbconfig->securityConfig->keyToUse = key_to_use; - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)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) diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 5ad6746696..e21859ded8 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -33,6 +33,7 @@ #include "rrc_defs.h" #include "rrc_proto.h" #include "assertions.h" +#include "rrc_vars.h" typedef uint32_t channel_t; @@ -50,7 +51,7 @@ nr_mac_rrc_data_ind_ue( 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"); + AssertFatal( nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len, 0, 0) == 0, "UE decode BCCH-DL-SCH error!\n"); break; default: break; @@ -59,13 +60,36 @@ nr_mac_rrc_data_ind_ue( return(0); } -int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP, +int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, const int CC_id, + const uint8_t gNB_id, const frame_t frameP, const rb_id_t Srb_id, - uint8_t *const buffer_pP ){ + uint8_t *buffer_pP){ - // todo + switch(Srb_id){ + + case CCCH: + + // TODO: Enable timer T300 + //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_active = 1; + //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_cnt = 0; + + LOG_D(NR_RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); + memcpy(buffer_pP, (uint8_t*)NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.Payload, NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size); + for(int i = 0; i= MAKE_VERSION(9, 0, 0)) ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif @@ -413,6 +414,18 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ for(nr_ue=0;nr_uemodule_id].MBMS_flag < 3) // see -Q option if (AMF_MODE_ENABLED) { - rrc_ue_generate_RRCSetupRequest( ctxt_pP, gNB_index ); + nr_rrc_ue_generate_RRCSetupRequest( ctxt_pP->module_id, gNB_index ); } if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_IDLE) { @@ -1028,205 +1041,120 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index 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; +int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) { - 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]; + if(sib1.si_SchedulingInfo) { + + bool SIB_to_request[32] = {}; + + LOG_D(RRC, "SIBs broadcasting: "); + for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { + printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2); } + printf("\n"); - 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_D(RRC, "SIBs needed by UE: "); + for(int j = 0; j < 8*requested_SI_List.size; j++) { + if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) { - 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; + printf("SIB%i ", j + 2); - 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)] ); + SIB_to_request[j] = true; + for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) { + if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) { + SIB_to_request[j] = false; + break; + } } - LOG_I( RRC, "siSchedulingInfoSIBType[%d] : %s\n", i, temp ); + } + } + printf("\n"); + + LOG_D(RRC, "SIBs to request by UE: "); + bool do_ra = false; + for(int j = 0; j < 8*requested_SI_List.size; j++) { + if(SIB_to_request[j]) { + printf("SIB%i ", j + 2); + do_ra = true; + } + } + printf("\n"); + + if(do_ra) { + + NR_UE_rrc_inst[module_id].ra_trigger = REQUEST_FOR_OTHER_SI; + get_softmodem_params()->do_ra = 1; + + if(sib1.si_SchedulingInfo->si_RequestConfig) { + LOG_D(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger); } else { - LOG_I( RRC, "mapping list %d is null\n", i ); + LOG_D(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger); } + } - } 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 ) { +int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) { + + switch(NR_UE_rrc_inst[module_id].ra_trigger){ + case INITIAL_ACCESS_FROM_RRC_IDLE: + // After SIB1 is received, prepare RRCConnectionRequest + nr_rrc_ue_generate_RRCSetupRequest(module_id,gNB_index); + break; + case RRC_CONNECTION_REESTABLISHMENT: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case DURING_HANDOVER: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case NON_SYNCHRONISED: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case TRANSITION_FROM_RRC_INACTIVE: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case TO_ESTABLISH_TA: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case REQUEST_FOR_OTHER_SI: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + case BEAM_FAILURE_RECOVERY: + AssertFatal(1==0, "ra_trigger not implemented yet!\n"); + break; + default: + AssertFatal(1==0, "Invalid ra_trigger value!\n"); + break; + } + + return 0; +} + +int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message( + module_id_t module_id, + 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]; + NR_SIB1_t *sib1 = NR_UE_rrc_inst[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)) { + if (((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) && // SIB1 received + (NR_UE_rrc_inst[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 ); - } + nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR ); asn_dec_rval_t dec_rval = uper_decode_complete( NULL, &asn_DEF_NR_BCCH_DL_SCH_Message, @@ -1234,11 +1162,15 @@ int nr_decode_BCCH_DLSCH_Message( (const void *)Sdu, Sdu_len ); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message ); + } + 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, + LOG_E( NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", + module_id, dec_rval.consumed ); - log_dump(RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" ); + log_dump(NR_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 ); @@ -1248,35 +1180,53 @@ int nr_decode_BCCH_DLSCH_Message( 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 ); + if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 0) { + NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index]; + if(sib1 != NULL){ + SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)sib1, 1 ); + } + + sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; + if (*(int64_t*)sib1 != 1) { + NR_UE_rrc_inst[module_id].sib1[gNB_index] = sib1; + if( g_log->log_component[NR_RRC].level >= OAILOG_DEBUG ) { + xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) NR_UE_rrc_inst[module_id].sib1[gNB_index]); + } + LOG_I(NR_RRC, "SIB1 decoded\n"); + + // FIXME: improve condition for the RA trigger + // Check for on-demand not broadcasted SI + check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); + if( nr_rrc_get_state(module_id) == RRC_STATE_IDLE_NR ) { + NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE; + // TODO: remove flag after full RA procedures implemented + get_softmodem_params()->do_ra = 1; + } + nr_rrc_ue_generate_ra_msg(module_id,gNB_index); + } else { + LOG_E(NR_RRC, "SIB1 not decoded\n"); } } - 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) { + if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) { + LOG_W(NR_RRC, "Decoding SI not implemented yet\n"); + // TODO: Decode SI + /* // SIB1 with schedulingInfoList is available - NR_SystemInformation_t *si = NR_UE_rrc_inst[ctxt_pP->module_id].si[gNB_index]; + NR_SystemInformation_t *si = NR_UE_rrc_inst[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 ); + LOG_I(NR_RRC, "[UE %"PRIu8"] Decoding SI\n", module_id); nr_decode_SI( ctxt_pP, gNB_index ); - //if (nfapi_mode == 3) - //UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1; - } + if (nfapi_mode == 3) + UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1; + */ + } break; case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: @@ -1285,10 +1235,10 @@ int nr_decode_BCCH_DLSCH_Message( } } - if (nr_rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) { + if (nr_rrc_get_sub_state(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 ); + nr_rrc_ue_generate_RRCSetupRequest(module_id, 0); + nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_CONNECTING ); //} } @@ -1488,41 +1438,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB 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, @@ -1783,10 +1698,10 @@ nr_rrc_ue_process_securityModeCommand( } //----------------------------------------------------------------------------- -void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) { +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, 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) { + if(NR_UE_rrc_inst[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++) { @@ -1800,16 +1715,16 @@ void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, cons } 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); + NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size = + do_RRCSetupRequest( + module_id, + (uint8_t *)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload, + rv); + LOG_I(NR_RRC,"[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n", + module_id, NR_UE_rrc_inst[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]); + for (i=0; imodule_id].defaultDRB, // NULL); // Refresh DRBs @@ -2557,7 +2474,7 @@ void *rrc_nrue_task( void *args_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_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id, 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, diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 52bd6c564a..f4ce474657 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -77,6 +77,30 @@ typedef struct OAI_NR_UECapability_s { NR_UE_NR_Capability_t *UE_NR_Capability; } OAI_NR_UECapability_t; +typedef enum requested_SI_List_e { + SIB2 = 1, + SIB3 = 2, + SIB4 = 4, + SIB5 = 8, + SIB6 = 16, + SIB7 = 32, + SIB8 = 64, + SIB9 = 128 +} requested_SI_List_t; + +// 3GPP TS 38.300 Section 9.2.6 +typedef enum RA_trigger_e { + RA_NOT_RUNNING, + INITIAL_ACCESS_FROM_RRC_IDLE, + RRC_CONNECTION_REESTABLISHMENT, + DURING_HANDOVER, + NON_SYNCHRONISED, + TRANSITION_FROM_RRC_INACTIVE, + TO_ESTABLISH_TA, + REQUEST_FOR_OTHER_SI, + BEAM_FAILURE_RECOVERY, +} RA_trigger_t; + typedef struct NR_UE_RRC_INST_s { NR_MeasConfig_t *meas_config; @@ -99,10 +123,13 @@ typedef struct NR_UE_RRC_INST_s { NR_SRB_INFO_TABLE_ENTRY Srb2[NB_CNX_UE]; uint8_t MBMS_flag; - OAI_NR_UECapability_t *UECap; - uint8_t *UECapability; + OAI_NR_UECapability_t *UECap; + uint8_t *UECapability; uint8_t UECapability_size; + RA_trigger_t ra_trigger; + BIT_STRING_t requested_SI_List; + NR_SystemInformation_t *si[NB_CNX_UE]; NR_SIB1_t *sib1[NB_CNX_UE]; NR_SIB2_t *sib2[NB_CNX_UE]; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 4019248441..0acf6db634 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -86,12 +86,14 @@ 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 +/**\brief decode NR BCCH-DLSCH (SI) messages \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); + \param sduP pointer to buffer of ASN message BCCH-DLSCH + \param sdu_len length of buffer + \param rsrq RSRQ + \param rsrp RSRP*/ +int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len, const uint8_t rsrq, const uint8_t rsrp); /**\brief Decode NR DCCH from gNB, sent from lower layer through SRB3 \param module_id module id @@ -112,24 +114,25 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, cons /**\brief \param module_id module id \param CC_id component carrier id + \param gNB_index gNB index \param frame_t frameP \param rb_id_t SRB id \param buffer_pP pointer to buffer*/ -int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP, +int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, const int CC_id, + const uint8_t gNB_id, const frame_t frameP, const rb_id_t Srb_id, - uint8_t *const buffer_pP); - + uint8_t *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 module_id module id \param gNB_index gNB index */ -void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ); +void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index); /** @}*/ #endif diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c index 0c70e1c902..5c2375a079 100644 --- a/openair2/SIMULATION/NR_RRC/itti_sim.c +++ b/openair2/SIMULATION/NR_RRC/itti_sim.c @@ -623,7 +623,7 @@ int main( int argc, char **argv ) 0); NR_UE_rrc_inst[ctxt.module_id].Info[0].State = RRC_SI_RECEIVED; - rrc_ue_generate_RRCSetupRequest(&ctxt, 0); + nr_rrc_ue_generate_RRCSetupRequest(ctxt.module_id, 0); printf("Entering ITTI signals handler\n"); itti_wait_tasks_end(); diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h index 304dd07042..e845315922 100644 --- a/openair2/UTIL/OSA/osa_defs.h +++ b/openair2/UTIL/OSA/osa_defs.h @@ -48,11 +48,14 @@ typedef enum { NAS_INT_ALG = 0x02, RRC_ENC_ALG = 0x03, RRC_INT_ALG = 0x04, - UP_ENC_ALG = 0x05 + UP_ENC_ALG = 0x05, + UP_INT_ALG = 0x06 } algorithm_type_dist_t; //int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB); +int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB); + 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, diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c index 71c7793fa0..159ee7f159 100644 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ b/openair2/UTIL/OSA/osa_key_deriver.c @@ -159,3 +159,27 @@ int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB) return 0; } */ + +int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) +{ + uint8_t *out; + uint8_t s[5]; + + /* FC is 0x1c (see 3gpp 33.401 annex A.15) */ + s[0] = 0x1c; + + /* put sk_counter */ + s[1] = (sk_counter >> 8) & 0xff; + s[2] = sk_counter & 0xff; + + /* put length of sk_counter (2) */ + s[3] = 0x00; + s[4] = 0x02; + + kdf(s, 5, keNB, 32, &out, 32); + + memcpy(skgNB, out, 32); + free(out); + + return 0; +} diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 58535646fd..321190015d 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -116,9 +116,7 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa /* some sanity check - to be refined at some point */ if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n"); - // Allow for a gracious exit when we kill first the gNB, then the eNB - //abort(); - return; + exit(1); } x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams; diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index fdce8678b0..7c3a89e7f4 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1318,6 +1318,9 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band); switch (instance_p->N_RB_DL[i]) { + case 24: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb24; + break; case 32: servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb32; break; diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index f0e0fa9c23..d60f7654ad 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -536,6 +536,14 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance, return -1; } + if((x2ap_eNB_data->state == X2AP_ENB_STATE_CONNECTED) || + (x2ap_eNB_data->state == X2AP_ENB_STATE_READY)) + + { + X2AP_ERROR("Received Unexpexted X2 Setup Response Message\n"); + return -1; + } + X2AP_DEBUG("Received a new X2 setup response\n"); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupResponse_IEs_t, ie, x2SetupResponse, @@ -662,6 +670,14 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance, return -1; } + if((x2ap_eNB_data->state == X2AP_ENB_STATE_CONNECTED) || + (x2ap_eNB_data->state == X2AP_ENB_STATE_READY)) + + { + X2AP_ERROR("Received Unexpexted X2 Setup Failure Message\n"); + return -1; + } + X2AP_DEBUG("Received a new X2 setup failure\n"); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupFailure_IEs_t, ie, x2SetupFailure, @@ -674,9 +690,11 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance, // need a FSM to handle all cases if ((ie->value.choice.Cause.present == X2AP_Cause_PR_misc) && (ie->value.choice.Cause.choice.misc == X2AP_CauseMisc_unspecified)) { - X2AP_WARN("Received X2 setup failure for eNB ... eNB is not ready\n"); + X2AP_ERROR("Received X2 setup failure for eNB ... eNB is not ready\n"); + exit(1); } else { X2AP_ERROR("Received x2 setup failure for eNB... please check your parameters\n"); + exit(1); } x2ap_eNB_data->state = X2AP_ENB_STATE_WAITING; @@ -730,6 +748,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } @@ -750,7 +769,11 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, //measResultListEUTRA.list.array[ncell_index]->physCellId; X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, X2AP_ProtocolIE_ID_id_GUMMEI_ID, true); - + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); + return -1; + } TBCD_TO_MCC_MNC(&ie->value.choice.ECGI.pLMN_Identity, X2AP_HANDOVER_REQ(msg).ue_gummei.mcc, X2AP_HANDOVER_REQ(msg).ue_gummei.mnc, X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len); OCTET_STRING_TO_INT8(&ie->value.choice.GUMMEI.mME_Code, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code); @@ -761,6 +784,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } @@ -872,6 +896,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } @@ -882,6 +907,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } @@ -912,6 +938,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n", __FILE__, __LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; }else{ if (ie->value.choice.E_RABs_Admitted_List.list.count > 0) { @@ -959,6 +986,12 @@ int x2ap_eNB_handle_handover_response (instance_t instance, X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); + return -1; + } + X2AP_TargeteNBtoSource_eNBTransparentContainer_t *c = &ie->value.choice.TargeteNBtoSource_eNBTransparentContainer; if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s */) @@ -1012,6 +1045,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } @@ -1022,6 +1056,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); return -1; } diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index 1144d9787e..8c1f46d3c9 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -1211,7 +1211,7 @@ int gtpv1u_eNB_init(void) { //gtpv1u_data_g.udp_data; RC.gtpv1u_data_g->seq_num = 0; RC.gtpv1u_data_g->restart_counter = 0; - + RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up = 0; /* Initializing GTPv1-U stack */ if ((rc = nwGtpv1uInitialize(&RC.gtpv1u_data_g->gtpv1u_stack, GTPU_STACK_ENB)) != NW_GTPV1U_OK) { LOG_E(GTPU, "Failed to setup nwGtpv1u stack %x\n", rc); diff --git a/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c b/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c index 8ac43cf7b1..637d930226 100644 --- a/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c +++ b/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c @@ -190,7 +190,6 @@ int decode_attach_accept(attach_accept_msg *attach_accept, uint8_t *buffer, uint default: errorCodeDecoder = TLV_DECODE_UNEXPECTED_IEI; LOG_TRACE(WARNING, "DECODE_UNEXPECTED_IEI %x (4 bits)", ieiDecoded); - AssertFatal(0, " "); return TLV_DECODE_UNEXPECTED_IEI; } } diff --git a/openair3/NAS/COMMON/IES/SupportedCodecList.c b/openair3/NAS/COMMON/IES/SupportedCodecList.c index 3a69eee366..15a2fecaa0 100644 --- a/openair3/NAS/COMMON/IES/SupportedCodecList.c +++ b/openair3/NAS/COMMON/IES/SupportedCodecList.c @@ -43,13 +43,17 @@ int decode_supported_codec_list(SupportedCodecList *supportedcodeclist, uint8_t CHECK_LENGTH_DECODER(len - decoded, ielen); supportedcodeclist->systemidentification = *(buffer + decoded); decoded++; + ielen--; supportedcodeclist->lengthofbitmap = *(buffer + decoded); decoded++; + ielen--; //IES_DECODE_U16(supportedcodeclist->codecbitmap, *(buffer + decoded)); IES_DECODE_U16(buffer, decoded, supportedcodeclist->codecbitmap); + ielen=ielen -2; #if defined (NAS_DEBUG) dump_supported_codec_list_xml(supportedcodeclist, iei); #endif + decoded = decoded + ielen; return decoded; } int encode_supported_codec_list(SupportedCodecList *supportedcodeclist, uint8_t iei, uint8_t *buffer, uint32_t len) diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index 99a3763dea..10b118eac0 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -443,14 +443,14 @@ static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm EPS_MOBILITY_MANAGEMENT_MESSAGE) { /* Process EMM data */ rc = _emm_as_recv(user, plain_msg, bytes, emm_cause); + free(plain_msg); } else if (header.protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) { const OctetString data = {bytes, (uint8_t *)plain_msg}; /* Foward ESM data to EPS session management */ rc = lowerlayer_data_ind(user, &data); + free(plain_msg); } - - free(plain_msg); } } else { /* Process successfull lower layer transfer indication */ diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index 67bfaf784e..b27270fadc 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -296,16 +296,16 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, else { /* Setup EMM cause code */ emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED; - - /* Release security mode control internal data */ - if (security_data->kenb.value) { - free(security_data->kenb.value); - security_data->kenb.value = NULL; - security_data->kenb.length = 0; - } } } + /* Release security mode control internal data */ + if (security_data->kenb.value) { + free(security_data->kenb.value); + security_data->kenb.value = NULL; + security_data->kenb.length = 0; + } + /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); diff --git a/openair3/S1AP/s1ap_common.h b/openair3/S1AP/s1ap_common.h index 77d03f4ae4..efac0201a3 100644 --- a/openair3/S1AP/s1ap_common.h +++ b/openair3/S1AP/s1ap_common.h @@ -106,7 +106,12 @@ extern int asn1_xer_print; if (ie == NULL ) { \ S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\ } \ - if (mandatory) DevAssert(ie != NULL); \ + if (mandatory) { \ + if (ie == NULL) { \ + S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\ + return -1; \ + } \ + } \ } while(0) /** \brief Function callback prototype. **/ diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 31ea3359da..e528c9e53e 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -73,6 +73,42 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); +static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, + s1ap_eNB_mme_data_t *s1ap_mme_data_p); +void s1ap_eNB_timer_expired(instance_t instance, + timer_has_expired_t *msg_p); + +int s1ap_timer_setup( + uint32_t interval_sec, + uint32_t interval_us, + task_id_t task_id, + int32_t instance, + uint32_t timer_kind, + timer_type_t type, + void *timer_arg, + long *timer_id) +{ + uint32_t *timeoutArg=NULL; + int ret=0; + timeoutArg=malloc(sizeof(uint32_t)); + *timeoutArg=timer_kind; + ret=timer_setup(interval_sec, + interval_us, + task_id, + instance, + type, + (void*)timeoutArg, + timer_id); + return ret; +} + +int s1ap_timer_remove(long timer_id) +{ + int ret; + ret=timer_remove(timer_id); + return ret; +} + uint32_t s1ap_generate_eNB_id(void) { char *out; char hostname[50]; @@ -98,7 +134,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, MessageDef *message_p = NULL; sctp_new_association_req_t *sctp_new_association_req_p = NULL; s1ap_eNB_mme_data_t *s1ap_mme_data_p = NULL; - struct s1ap_eNB_mme_data_s *mme = NULL; +// 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, 0, SCTP_NEW_ASSOCIATION_REQ); @@ -114,51 +150,32 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, local_ip_addr, sizeof(*local_ip_addr)); S1AP_INFO("[eNB %ld] check the mme registration state\n",instance_p->instance); - mme = NULL; + /* Create new MME descriptor */ + s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p)); + DevAssert(s1ap_mme_data_p != NULL); + s1ap_mme_data_p->cnx_id = s1ap_eNB_fetch_add_global_cnx_id(); + sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; + s1ap_mme_data_p->assoc_id = -1; + s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num; + 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]; - if ( mme == NULL ) { - /* Create new MME descriptor */ - s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p)); - DevAssert(s1ap_mme_data_p != NULL); - s1ap_mme_data_p->cnx_id = s1ap_eNB_fetch_add_global_cnx_id(); - sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; - s1ap_mme_data_p->assoc_id = -1; - s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num; - 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]; - - s1ap_mme_data_p->s1ap_eNB_instance = instance_p; - STAILQ_INIT(&s1ap_mme_data_p->served_gummei); - /* Insert the new descriptor in list of known MME - * but not yet associated. - */ - RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p); - s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING; - instance_p->s1ap_mme_nb ++; - instance_p->s1ap_mme_pending_nb ++; - } 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 %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); - /*s1ap_mme_data_p->cnx_id = mme->cnx_id; - sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id; - - s1ap_mme_data_p->assoc_id = -1; - s1ap_mme_data_p->s1ap_eNB_instance = instance_p; - */ - } else { - 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); - } + s1ap_mme_data_p->s1ap_eNB_instance = instance_p; + STAILQ_INIT(&s1ap_mme_data_p->served_gummei); + /* Insert the new descriptor in list of known MME + * but not yet associated. + */ + RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p); + s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED; + memcpy( &(s1ap_mme_data_p->mme_ip_address), mme_ip_address, sizeof(net_ip_address_t) ); + s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD; + s1ap_mme_data_p->sctp_req_cnt++; + s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT; + instance_p->s1ap_mme_pending_nb ++; itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); } @@ -196,10 +213,10 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * new_instance->eNB_id = s1ap_register_eNB->eNB_id; new_instance->cell_type = s1ap_register_eNB->cell_type; new_instance->tac = s1ap_register_eNB->tac; - + memcpy(&new_instance->eNB_s1_ip, - &s1ap_register_eNB->enb_ip_address, - sizeof(s1ap_register_eNB->enb_ip_address)); + &s1ap_register_eNB->enb_ip_address, + sizeof(s1ap_register_eNB->enb_ip_address)); for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) { new_instance->mcc[i] = s1ap_register_eNB->mcc[i]; @@ -207,6 +224,15 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * new_instance->mnc_digit_length[i] = s1ap_register_eNB->mnc_digit_length[i]; } + memcpy( &(new_instance->enb_ip_address), &(s1ap_register_eNB->enb_ip_address), sizeof(net_ip_address_t) ); + new_instance->s1_setuprsp_wait_timer = s1ap_register_eNB->s1_setuprsp_wait_timer; + new_instance->s1_setupreq_wait_timer = s1ap_register_eNB->s1_setupreq_wait_timer; + new_instance->s1_setupreq_count = s1ap_register_eNB->s1_setupreq_count; + new_instance->sctp_req_timer = s1ap_register_eNB->sctp_req_timer; + new_instance->sctp_req_count = s1ap_register_eNB->sctp_req_count; + new_instance->sctp_in_streams = s1ap_register_eNB->sctp_in_streams; + new_instance->sctp_out_streams = s1ap_register_eNB->sctp_out_streams; + new_instance->num_plmn = s1ap_register_eNB->num_plmn; new_instance->default_drx = s1ap_register_eNB->default_drx; /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ @@ -217,8 +243,12 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * s1ap_register_eNB->eNB_id); } - DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, - S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0); + if( s1ap_register_eNB->nb_mme > S1AP_MAX_NB_MME_IP_ADDRESS ) + { + S1AP_ERROR("Invalid MME number = %d\n ", s1ap_register_eNB->nb_mme); + s1ap_register_eNB->nb_mme = S1AP_MAX_NB_MME_IP_ADDRESS; + } + new_instance->s1ap_mme_nb = s1ap_register_eNB->nb_mme; /* Trying to connect to provided list of MME ip address */ for (index = 0; index < s1ap_register_eNB->nb_mme; index++) { @@ -250,28 +280,131 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { s1ap_eNB_instance_t *instance_p; s1ap_eNB_mme_data_t *s1ap_mme_data_p; + s1ap_eNB_ue_context_t *ue_p = NULL; + MessageDef *message_p = NULL; + uint32_t timer_kind = 0; + struct plmn_identity_s* plmnInfo; + struct served_group_id_s* groupInfo; + struct served_gummei_s* gummeiInfo; + struct mme_code_s* mmeCode; + int8_t cnt = 0; + unsigned enb_s1ap_id[NUMBER_OF_UE_MAX]; DevAssert(sctp_new_association_resp != NULL); instance_p = s1ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); s1ap_mme_data_p = s1ap_eNB_get_MME(instance_p, -1, sctp_new_association_resp->ulp_cnx_id); 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 %ld, cnx_id %u\n", - sctp_new_association_resp->sctp_state, - instance, - sctp_new_association_resp->ulp_cnx_id); - s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); - return; + memset(enb_s1ap_id, 0, sizeof(enb_s1ap_id) ); + if( s1ap_mme_data_p->timer_id != S1AP_TIMERID_INIT ) { + s1ap_timer_remove( s1ap_mme_data_p->timer_id ); + s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT; } + + if( sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED ) { + RB_FOREACH(ue_p, s1ap_ue_map, &instance_p->s1ap_ue_head) { + if( ue_p->mme_ref == s1ap_mme_data_p ) { + if(cnt < NUMBER_OF_UE_MAX) { + enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id; + cnt++; + + message_p = NULL; + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND); + + if( message_p != NULL ) { + S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = ue_p->eNB_ue_s1ap_id; + + if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) { + S1AP_ERROR("UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); + } + } else { + S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); + } + }else{ + S1AP_ERROR("s1ap_eNB_handle_sctp_association_resp: cnt %d > max\n", cnt); + } + } + } + for( ; cnt > 0 ; ) { + cnt--; + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + struct s1ap_eNB_ue_context_s *s1ap_ue_context_p = NULL; + ue_context_p = s1ap_eNB_get_ue_context(instance_p, (uint32_t)enb_s1ap_id[cnt]); + if (ue_context_p != NULL) { + s1ap_ue_context_p = RB_REMOVE(s1ap_ue_map, &instance_p->s1ap_ue_head, ue_context_p); + s1ap_eNB_free_ue_context(s1ap_ue_context_p); + } + } + s1ap_mme_data_p->mme_name = 0; + s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD; + s1ap_mme_data_p->nextstream = 0; + s1ap_mme_data_p->in_streams = 0; + s1ap_mme_data_p->out_streams = 0; + s1ap_mme_data_p->assoc_id = -1; + + while (!STAILQ_EMPTY(&s1ap_mme_data_p->served_gummei)) { + gummeiInfo = STAILQ_FIRST(&s1ap_mme_data_p->served_gummei); + STAILQ_REMOVE_HEAD(&s1ap_mme_data_p->served_gummei, next); - /* Update parameters */ - s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; - s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; - s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams; - /* Prepare new S1 Setup Request */ - s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p); + while (!STAILQ_EMPTY(&gummeiInfo->served_plmns)) { + plmnInfo = STAILQ_FIRST(&gummeiInfo->served_plmns); + STAILQ_REMOVE_HEAD(&gummeiInfo->served_plmns, next); + free(plmnInfo); + } + while (!STAILQ_EMPTY(&gummeiInfo->served_group_ids)) { + groupInfo = STAILQ_FIRST(&gummeiInfo->served_group_ids); + STAILQ_REMOVE_HEAD(&gummeiInfo->served_group_ids, next); + free(groupInfo); + } + while (!STAILQ_EMPTY(&gummeiInfo->mme_codes)) { + mmeCode = STAILQ_FIRST(&gummeiInfo->mme_codes); + STAILQ_REMOVE_HEAD(&gummeiInfo->mme_codes, next); + free(mmeCode); + } + free(gummeiInfo); + } + + STAILQ_INIT(&s1ap_mme_data_p->served_gummei); + + if( s1ap_mme_data_p->state == S1AP_ENB_STATE_DISCONNECTED ) { + if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) || + (instance_p->sctp_req_count == 0xffff) ) { + timer_kind = s1ap_mme_data_p->cnx_id; + timer_kind = timer_kind | S1AP_MMEIND; + timer_kind = timer_kind | SCTP_REQ_WAIT; + + if( s1ap_timer_setup( instance_p->sctp_req_timer, 0, TASK_S1AP, instance_p->instance, + timer_kind, S1AP_TIMER_ONE_SHOT, NULL, &s1ap_mme_data_p->timer_id) < 0 ) { + S1AP_ERROR("Timer Start NG(SCTP retransmission wait timer) : MME=%d\n",s1ap_mme_data_p->cnx_id); + s1ap_sctp_req( instance_p, s1ap_mme_data_p ); + } + } else { + S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id); + } + } else { + S1AP_ERROR("SCTP disconnection reception : MME = %d\n",s1ap_mme_data_p->cnx_id); + + if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) || + (instance_p->sctp_req_count == 0xffff) ) { + s1ap_sctp_req( instance_p, s1ap_mme_data_p ); + } else { + S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id); + } + s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED; + } + } else { + /* Update parameters */ + s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; + s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; + s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams; + /* Prepare new S1 Setup Request */ + s1ap_mme_data_p->s1_setupreq_cnt = 0; + s1ap_mme_data_p->sctp_req_cnt = 0; + if (s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p) == -1) { + S1AP_ERROR("s1ap eNB generate s1 setup request failed\n"); + return; + } + } } static @@ -282,13 +415,94 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { mme_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 - s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream, - sctp_data_ind->buffer, sctp_data_ind->buffer_length); + if (s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length) == -1) { + S1AP_ERROR("Failed to handle s1ap eNB message\n"); + } #endif result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } +void s1ap_eNB_timer_expired( + instance_t instance, + timer_has_expired_t *msg_p) +{ + uint32_t timer_kind = 0; + int16_t line_ind = 0; + s1ap_eNB_mme_data_t *mme_desc_p = NULL; + uint32_t timer_ind = 0; + s1ap_eNB_instance_t *instance_p = NULL; + long timer_id = S1AP_TIMERID_INIT; + + instance_p = s1ap_eNB_get_instance(instance); + if(msg_p->arg!=NULL){ + timer_kind = *((uint32_t*)msg_p->arg); + free(msg_p->arg); + }else{ + S1AP_ERROR("s1 timer timer_kind is NULL\n"); + return; + } + line_ind = (int16_t)(timer_kind & S1AP_LINEIND); + timer_id = msg_p->timer_id; + + if( (timer_kind & S1AP_MMEIND) == S1AP_MMEIND ) { + mme_desc_p = s1ap_eNB_get_MME(instance_p, -1, line_ind); + if(mme_desc_p != NULL) { + if( timer_id == mme_desc_p->timer_id ) { + mme_desc_p->timer_id = S1AP_TIMERID_INIT; + timer_ind = timer_kind & S1AP_TIMERIND; + + switch(timer_ind) + { + case S1_SETRSP_WAIT: + { + if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || + (instance_p->s1_setupreq_count == 0xffff) ) { + s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); + } else { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); + } + break; + } + case S1_SETREQ_WAIT: + { + if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || + (instance_p->s1_setupreq_count == 0xffff) ) { + s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); + } else { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); + } + break; + } + case SCTP_REQ_WAIT: + { + if( (instance_p->sctp_req_count >= mme_desc_p->sctp_req_cnt) || + (instance_p->sctp_req_count == 0xffff) ) { + s1ap_sctp_req( instance_p, mme_desc_p ); + } else { + S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind); + } + break; + } + default: + { + S1AP_WARN("Invalid Timer indication\n"); + break; + } + } + } else { + S1AP_DEBUG("Unmatch timer id\n"); + return; + } + } else { + S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind); + return; + } + } + return; +} + void s1ap_eNB_init(void) { S1AP_DEBUG("Starting S1AP layer\n"); s1ap_eNB_prepare_internal_data(); @@ -412,6 +626,13 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { } break; + case TIMER_HAS_EXPIRED: + { + s1ap_eNB_timer_expired(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &received_msg->ittiMsg.timer_has_expired); + } + break; + default: S1AP_ERROR("Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); @@ -452,6 +673,7 @@ static int s1ap_eNB_generate_s1_setup_request( uint8_t *buffer = NULL; uint32_t len = 0; int ret = 0; + uint32_t timer_kind = 0; DevAssert(instance_p != NULL); DevAssert(s1ap_mme_data_p != NULL); s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING; @@ -526,6 +748,17 @@ static int s1ap_eNB_generate_s1_setup_request( return -1; } + timer_kind = s1ap_mme_data_p->cnx_id; + timer_kind = timer_kind | S1AP_MMEIND; + timer_kind = timer_kind | S1_SETRSP_WAIT; + + if( s1ap_timer_setup(instance_p->s1_setuprsp_wait_timer, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT, + NULL, &s1ap_mme_data_p->timer_id) < 0 ) + { + S1AP_ERROR("Timer Start NG(S1 Setup Response) : MME=%d\n",s1ap_mme_data_p->cnx_id); + } + s1ap_mme_data_p->s1_setupreq_cnt++; + /* Non UE-Associated signalling -> stream = 0 */ s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0); return ret; @@ -534,3 +767,55 @@ static int s1ap_eNB_generate_s1_setup_request( +static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, + s1ap_eNB_mme_data_t *s1ap_mme_data_p) +{ + MessageDef *message_p = NULL; + sctp_new_association_req_t *sctp_new_association_req_p = NULL; + + if( instance_p == NULL ) + { + S1AP_ERROR("Invalid instance_p\n"); + return -1; + } + + 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->ppid = S1AP_SCTP_PPID; + sctp_new_association_req_p->in_streams = instance_p->sctp_in_streams; + sctp_new_association_req_p->out_streams = instance_p->sctp_out_streams; + sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; + + if( s1ap_mme_data_p->mme_ip_address.ipv4 != 0 ) { + memcpy(&sctp_new_association_req_p->remote_address, + &s1ap_mme_data_p->mme_ip_address, + sizeof(net_ip_address_t)); + if( instance_p->enb_ip_address.ipv4 != 0 ) { + memcpy(&sctp_new_association_req_p->local_address, + &instance_p->enb_ip_address, + sizeof(net_ip_address_t)); + } else { + S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n"); + return -1; + } + } else { + memcpy(&sctp_new_association_req_p->remote_address, + &s1ap_mme_data_p->mme_ip_address, + sizeof(net_ip_address_t)); + if( instance_p->enb_ip_address.ipv6 != 0 ) { + memcpy(&sctp_new_association_req_p->local_address, + &instance_p->enb_ip_address, + sizeof(net_ip_address_t)); + } else { + S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n"); + return -1; + } + } + + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); + + s1ap_mme_data_p->sctp_req_cnt++; + + return 0; +} diff --git a/openair3/S1AP/s1ap_eNB.h b/openair3/S1AP/s1ap_eNB.h index 2abbc53ec9..2183587214 100644 --- a/openair3/S1AP/s1ap_eNB.h +++ b/openair3/S1AP/s1ap_eNB.h @@ -30,6 +30,22 @@ #ifndef S1AP_ENB_H_ #define S1AP_ENB_H_ +#define S1AP_MMEIND 0x80000000 +#define S1AP_UEIND 0x00000000 +#define S1_SETRSP_WAIT 0x00010000 +#define S1_SETREQ_WAIT 0x00020000 +#define SCTP_REQ_WAIT 0x00030000 +#define S1AP_LINEIND 0x0000ffff +#define S1AP_TIMERIND 0x00ff0000 + +#define S1AP_TIMERID_INIT 0xffffffffffffffff + +typedef enum s1ap_timer_type_s { + S1AP_TIMER_PERIODIC, + S1AP_TIMER_ONE_SHOT, + S1AP_TIMER_TYPE_MAX, +} s1ap_timer_type_t; + typedef struct s1ap_eNB_config_s { // MME related params unsigned char mme_enabled; ///< MME enabled ? @@ -43,6 +59,7 @@ void *s1ap_eNB_process_itti_msg(void*); void s1ap_eNB_init(void); void *s1ap_eNB_task(void *arg); +int s1ap_timer_remove(long timer_id); uint32_t s1ap_generate_eNB_id(void); #endif /* S1AP_ENB_H_ */ diff --git a/openair3/S1AP/s1ap_eNB_decoder.c b/openair3/S1AP/s1ap_eNB_decoder.c index 4635946a05..14e4b49238 100644 --- a/openair3/S1AP/s1ap_eNB_decoder.c +++ b/openair3/S1AP/s1ap_eNB_decoder.c @@ -89,8 +89,6 @@ static int s1ap_eNB_decode_initiating_message(S1AP_S1AP_PDU_t *pdu) { default: S1AP_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; } diff --git a/openair3/S1AP/s1ap_eNB_defs.h b/openair3/S1AP/s1ap_eNB_defs.h index d8a8da8001..ed0909d66e 100644 --- a/openair3/S1AP/s1ap_eNB_defs.h +++ b/openair3/S1AP/s1ap_eNB_defs.h @@ -165,6 +165,12 @@ typedef struct s1ap_eNB_mme_data_s { /* Only meaningfull in virtual mode */ struct s1ap_eNB_instance_s *s1ap_eNB_instance; + + uint32_t nb_calls; + net_ip_address_t mme_ip_address; + long timer_id; + uint16_t s1_setupreq_cnt; + uint16_t sctp_req_cnt; } s1ap_eNB_mme_data_t; typedef struct s1ap_eNB_instance_s { @@ -217,6 +223,14 @@ typedef struct s1ap_eNB_instance_s { /* Default Paging DRX of the eNB as defined in TS 36.304 */ paging_drx_t default_drx; + net_ip_address_t enb_ip_address; + uint16_t s1_setuprsp_wait_timer; + uint16_t s1_setupreq_wait_timer; + uint16_t s1_setupreq_count; + uint16_t sctp_req_timer; + uint16_t sctp_req_count; + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; } s1ap_eNB_instance_t; typedef struct { diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 7c233d9e14..9ee3287b94 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -38,6 +38,9 @@ #include "s1ap_eNB_defs.h" #include "s1ap_eNB_handlers.h" #include "s1ap_eNB_decoder.h" +#include "s1ap_eNB_encoder.h" + +#include "s1ap_eNB_itti_messaging.h" #include "s1ap_eNB_ue_context.h" #include "s1ap_eNB_trace.h" @@ -109,6 +112,20 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t as uint32_t stream, S1AP_S1AP_PDU_t *pdu); +static int s1ap_eNB_snd_s1_setup_request( + s1ap_eNB_instance_t *instance_p, + s1ap_eNB_mme_data_t *s1ap_mme_data_p); + +int s1ap_timer_setup( + uint32_t interval_sec, + uint32_t interval_us, + task_id_t task_id, + int32_t instance, + uint32_t timer_kind, + timer_type_t type, + void *timer_arg, + long *timer_id); + /* Handlers matrix. Only eNB related procedure present here */ s1ap_message_decoded_callback messages_callback[][3] = { { 0, 0, 0 }, /* HandoverPreparation */ @@ -260,6 +277,10 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, S1AP_S1SetupFailure_t *container; S1AP_S1SetupFailureIEs_t *ie; s1ap_eNB_mme_data_t *mme_desc_p; + uint32_t interval_sec = 0; + uint32_t timer_kind = 0; + s1ap_eNB_instance_t *instance_p; + DevAssert(pdu != NULL); container = &pdu->choice.unsuccessfulOutcome.value.choice.S1SetupFailure; @@ -270,7 +291,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { - S1AP_ERROR("[SCTP %d] Received S1 setup response for non existing " + S1AP_ERROR("[SCTP %d] Received S1 setup failure for non existing " "MME context\n", assoc_id); return -1; } @@ -278,6 +299,10 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container, S1AP_ProtocolIE_ID_id_Cause,true); + if(ie == NULL) { + return -1; + } + if ((ie->value.choice.Cause.present == S1AP_Cause_PR_misc) && (ie->value.choice.Cause.choice.misc == S1AP_CauseMisc_unspecified)) { S1AP_WARN("Received s1 setup failure for MME... MME is not ready\n"); @@ -285,8 +310,56 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n"); } - mme_desc_p->state = S1AP_ENB_STATE_WAITING; - s1ap_handle_s1_setup_message(mme_desc_p, 0); + if( mme_desc_p->timer_id != S1AP_TIMERID_INIT ) { + s1ap_timer_remove( mme_desc_p->timer_id ); + mme_desc_p->timer_id = S1AP_TIMERID_INIT; + } + instance_p = mme_desc_p->s1ap_eNB_instance; + if( ( instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || + ( instance_p->s1_setupreq_count == 0xffff) ) { + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_TimeToWait, false); + if( ie != NULL ) { + switch(ie->value.choice.TimeToWait) + { + case S1AP_TimeToWait_v1s: + interval_sec = 1; + break; + case S1AP_TimeToWait_v2s: + interval_sec = 2; + break; + case S1AP_TimeToWait_v5s: + interval_sec = 5; + break; + case S1AP_TimeToWait_v10s: + interval_sec = 10; + break; + case S1AP_TimeToWait_v20s: + interval_sec = 20; + break; + case S1AP_TimeToWait_v60s: + interval_sec = 60; + break; + default: + interval_sec = instance_p->s1_setupreq_wait_timer; + break; + } + } else { + interval_sec = instance_p->s1_setupreq_wait_timer; + } + + timer_kind = mme_desc_p->cnx_id; + timer_kind = timer_kind | S1AP_MMEIND; + timer_kind = timer_kind | S1_SETREQ_WAIT; + + if( s1ap_timer_setup(interval_sec, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT, + NULL, &mme_desc_p->timer_id) < 0 ) { + S1AP_ERROR("Timer Start NG(S1 Setup Request) : MME=%d\n",mme_desc_p->cnx_id); + s1ap_eNB_snd_s1_setup_request( instance_p, mme_desc_p ); + } + } else { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",mme_desc_p->cnx_id); + } return 0; } @@ -314,9 +387,27 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, return -1; } + /* Set the capacity of this MME */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); + if(ie == NULL) { + return -1; + } + mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_ServedGUMMEIs, true); + if(ie == NULL) { + return -1; + } + if( mme_desc_p->timer_id != S1AP_TIMERID_INIT ) + { + s1ap_timer_remove( mme_desc_p->timer_id ); + mme_desc_p->timer_id = S1AP_TIMERID_INIT; + } + mme_desc_p->s1_setupreq_cnt = 0; + mme_desc_p->sctp_req_cnt = 0; /* The list of served gummei can contain at most 8 elements. * LTE related gummei is the first element in the list, i.e with an id of 0. */ @@ -368,13 +459,7 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, STAILQ_INSERT_TAIL(&mme_desc_p->served_gummei, new_gummei_p, next); } - - /* Set the capacity of this MME */ - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); - - mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; - + /* Optionaly set the mme name */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MMEname, false); @@ -392,7 +477,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, */ mme_desc_p->state = S1AP_ENB_STATE_CONNECTED; mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++; - s1ap_handle_s1_setup_message(mme_desc_p, 0); return 0; } @@ -725,6 +809,9 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, S1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false); if (ie) { + if( ie->value.choice.CriticalityDiagnostics.procedureCode ) { + S1AP_WARN("Received S1 Error indication CriticalityDiagnostics procedureCode = %ld\n", *ie->value.choice.CriticalityDiagnostics.procedureCode); + } // TODO continue } @@ -807,9 +894,11 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, &(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl)); /* id-E-RABToBeSetupListCtxtSUReq */ } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeSetupListCtxtSUReq, true); @@ -852,6 +941,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability; } /* for i... */ } else {/* ie != NULL */ + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -864,21 +954,37 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); - /* id-SecurityKey : Copy the security key */ } else {/* ie != NULL */ + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } + /* id-SecurityKey : Copy the security key */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_SecurityKey, true); if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); - itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); } else {/* ie != NULL */ + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } + + /* id-NRUESecurityCapabilities */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_NRUESecurityCapabilities, false); + if (ie != NULL) { + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms); + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms); + } else { + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = 0; + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = 0; + } + + itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); return 0; } @@ -904,6 +1010,13 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, return -1; } + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container, + S1AP_ProtocolIE_ID_id_Cause, true); + if( ie == NULL ) { + S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(Cause)\n" ); + return -1; + } + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_UE_S1AP_IDs, true); @@ -951,9 +1064,26 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, //#warning "TODO mapping mme_ue_s1ap_id enb_ue_s1ap_id?" case S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID: - mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; - S1AP_ERROR("TO DO mapping mme_ue_s1ap_id enb_ue_s1ap_id"); - (void)mme_ue_s1ap_id; /* TODO: remove - it's to remove gcc warning about unused var */ + mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.mME_UE_S1AP_ID; + + RB_FOREACH(ue_desc_p, s1ap_ue_map, &mme_desc_p->s1ap_eNB_instance->s1ap_ue_head) + { + if( ue_desc_p->mme_ue_s1ap_id == mme_ue_s1ap_id ) + { + enb_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id; + + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND); + S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; + itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); + + return 0; + } + } + S1AP_ERROR("[SCTP %d] Received UE context release command(mME_UE_S1AP_ID) for non " + "existing UE context 0x%06lx\n", + assoc_id, + mme_ue_s1ap_id); + return -1; case S1AP_UE_S1AP_IDs_PR_NOTHING: default: @@ -961,12 +1091,10 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, return -1; } } else { + S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(UE_S1AP_IDs)\n" ); return -1; } - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container, - S1AP_ProtocolIE_ID_id_Cause, true); - /* TBD */ } static @@ -985,7 +1113,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, container = &pdu->choice.initiatingMessage.value.choice.E_RABSetupRequest; if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { - S1AP_ERROR("[SCTP %d] Received initial context setup request for non " + S1AP_ERROR("[SCTP %d] Received E-RAB setup request for non " "existing MME context\n", assoc_id); return -1; } @@ -1012,7 +1140,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, enb_ue_s1ap_id)) == NULL) { - S1AP_ERROR("[SCTP %d] Received initial context setup request for non " + S1AP_ERROR("[SCTP %d] Received E-RAB setup request for non " "existing UE context 0x%06lx\n", assoc_id, enb_ue_s1ap_id); return -1; @@ -1085,6 +1213,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1105,13 +1234,6 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, // received Paging Message from MME S1AP_DEBUG("[SCTP %d] Received Paging Message From MME\n",assoc_id); - /* Paging procedure -> stream != 0 */ - if (stream == 0) { - LOG_W(S1AP,"[SCTP %d] Received Paging procedure on stream (%d)\n", - assoc_id, stream); - return -1; - } - if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { S1AP_ERROR("[SCTP %d] Received Paging for non " "existing MME context\n", assoc_id); @@ -1139,6 +1261,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code = 0; S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi = 0; } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1166,6 +1289,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, if(i != ie->value.choice.UEPagingID.choice.iMSI.size - 1) { /* invalid paging_p->uePagingID.choise.iMSI.buffer */ S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI error(i %d 0x0F)\n", assoc_id,i); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } } else { @@ -1176,14 +1300,17 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length >= S1AP_IMSI_LENGTH) { /* invalid paging_p->uePagingID.choise.iMSI.size */ S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI.size(%d) is over IMSI length(%d)\n", assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length, S1AP_IMSI_LENGTH); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } } else { /* of if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_iMSI) */ /* invalid paging_p->uePagingID.present */ S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.present(%d) is unknown\n", assoc_id, ie->value.choice.UEPagingID.present); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } } else { /* of ie != NULL */ + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1216,6 +1343,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, return -1; } } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1243,6 +1371,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, S1AP_PAGING_IND(message_p).tac[i]); } } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1337,6 +1466,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id; } } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1389,6 +1519,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); } else { /* of if (ie != NULL)*/ + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1462,6 +1593,24 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, 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-E-RABToBeReleasedList */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_E_RABToBeReleasedList, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = ie->value.choice.E_RABList.list.count; + + for (i = 0; i < ie->value.choice.E_RABList.list.count; i++) { + S1AP_E_RABItem_t *item_p; + item_p = &(((S1AP_E_RABItemIEs_t *)ie->value.choice.E_RABList.list.array[i])->value.choice.E_RABItem); + S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID; + S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID); + } + } else { + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); + return -1; + } + /* id-NAS-PDU */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, S1AP_ProtocolIE_ID_id_NAS_PDU, false); @@ -1477,24 +1626,6 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = 0; S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL; } - - /* id-E-RABToBeReleasedList */ - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_E_RABToBeReleasedList, true); - - if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ - S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = ie->value.choice.E_RABList.list.count; - - for (i = 0; i < ie->value.choice.E_RABList.list.count; i++) { - S1AP_E_RABItem_t *item_p; - item_p = &(((S1AP_E_RABItemIEs_t *)ie->value.choice.E_RABList.list.array[i])->value.choice.E_RABItem); - S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID; - S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID); - } - } else { - return -1; - } - itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); return 0; } @@ -1519,7 +1650,6 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, if (stream == 0) { S1AP_ERROR("[SCTP %d] Received s1 path switch request ack on stream (%d)\n", assoc_id, stream); - //return -1; } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { @@ -1536,6 +1666,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, if (ie == NULL) { S1AP_ERROR("[SCTP %d] Received path switch request ack for non " "ie context is NULL\n", assoc_id); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1558,6 +1689,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, if (ie == NULL) { S1AP_ERROR("[SCTP %d] Received path switch request ack for non " "ie context is NULL\n", assoc_id); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1575,6 +1707,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, if (ie == NULL) { S1AP_ERROR("[SCTP %d] Received path switch request ack for non " "ie context is NULL\n", assoc_id); + itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } @@ -1588,14 +1721,10 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, S1AP_ProtocolIE_ID_id_uEaggregateMaximumBitrate, false); if (ie) { - OCTET_STRING_TO_INT32 ( - &ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL, - S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul - ); - OCTET_STRING_TO_INT32 ( - &ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL, - S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl - ); + asn_INTEGER2ulong(&ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL, + &S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul); + asn_INTEGER2ulong(&ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL, + &S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl); } else { S1AP_WARN("UEAggregateMaximumBitrate not supported\n"); S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul = 0; @@ -1674,9 +1803,8 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_ pathSwitchRequestFailure = &pdu->choice.unsuccessfulOutcome.value.choice.PathSwitchRequestFailure; if (stream != 0) { - S1AP_ERROR("[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)\n", + S1AP_WARN("[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)\n", assoc_id, stream); - return -1; } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { @@ -1740,3 +1868,144 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t as return 0; } +//----------------------------------------------------------------------------- +/* +* eNB generate a S1 setup request towards MME +*/ +static int s1ap_eNB_snd_s1_setup_request( + s1ap_eNB_instance_t *instance_p, + s1ap_eNB_mme_data_t *s1ap_mme_data_p) +//----------------------------------------------------------------------------- +{ + S1AP_S1AP_PDU_t pdu; + S1AP_S1SetupRequest_t *out = NULL; + S1AP_S1SetupRequestIEs_t *ie = NULL; + S1AP_SupportedTAs_Item_t *ta = NULL; + S1AP_PLMNidentity_t *plmn = NULL; + uint8_t *buffer = NULL; + uint32_t len = 0; + int ret = 0; + uint32_t timer_kind = 0; + + DevAssert(instance_p != NULL); + DevAssert(s1ap_mme_data_p != NULL); + s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING; + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_S1Setup; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_S1SetupRequest; + out = &pdu.choice.initiatingMessage.value.choice.S1SetupRequest; + /* mandatory */ + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_Global_ENB_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_Global_ENB_ID; + MCC_MNC_TO_PLMNID(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[0]], + instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[0]], + instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[0]], + &ie->value.choice.Global_ENB_ID.pLMNidentity); + ie->value.choice.Global_ENB_ID.eNB_ID.present = S1AP_ENB_ID_PR_macroENB_ID; + MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, + &ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID); + S1AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, + ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[0], + ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[1], + ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[2]); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (instance_p->eNB_name) { + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNBname; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_ENBname; + OCTET_STRING_fromBuf(&ie->value.choice.ENBname, instance_p->eNB_name, + strlen(instance_p->eNB_name)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_SupportedTAs; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_SupportedTAs; + { + ta = (S1AP_SupportedTAs_Item_t *)calloc(1, sizeof(S1AP_SupportedTAs_Item_t)); + INT16_TO_OCTET_STRING(instance_p->tac, &ta->tAC); + { + for (int i = 0; i < s1ap_mme_data_p->broadcast_plmn_num; ++i) { + plmn = (S1AP_PLMNidentity_t *)calloc(1, sizeof(S1AP_PLMNidentity_t)); + MCC_MNC_TO_TBCD(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[i]], + instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[i]], + instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[i]], + plmn); + ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn); + } + } + ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAs.list, ta); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_DefaultPagingDRX; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_PagingDRX; + ie->value.choice.PagingDRX = instance_p->default_drx; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (0) { + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CSG_IdList; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_CSG_IdList; + // ie->value.choice.CSG_IdList = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ +#if (S1AP_VERSION >= MAKE_VERSION(13, 0, 0)) + + if (0) { + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_UE_RetentionInformation; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_UE_RetentionInformation; + // ie->value.choice.UE_RetentionInformation = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + if (0) { + ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_NB_IoT_DefaultPagingDRX; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_S1SetupRequestIEs__value_PR_NB_IoT_DefaultPagingDRX; + // ie->value.choice.NB_IoT_DefaultPagingDRX = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + +#endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ + + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + S1AP_ERROR("Failed to encode S1 setup request\n"); + return -1; + } + + timer_kind = s1ap_mme_data_p->cnx_id; + timer_kind = timer_kind | S1AP_MMEIND; + timer_kind = timer_kind | S1_SETRSP_WAIT; + + if( s1ap_timer_setup(instance_p->s1_setuprsp_wait_timer, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT, + NULL, &s1ap_mme_data_p->timer_id) < 0 ) + { + S1AP_ERROR("Timer Start NG(S1 Setup Response) : MME=%d\n",s1ap_mme_data_p->cnx_id); + } + s1ap_mme_data_p->s1_setupreq_cnt++; + + /* Non UE-Associated signalling -> stream = 0 */ + s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0); + return ret; +} diff --git a/openair3/S1AP/s1ap_eNB_management_procedures.c b/openair3/S1AP/s1ap_eNB_management_procedures.c index fc7ae70e49..a870e975a2 100644 --- a/openair3/S1AP/s1ap_eNB_management_procedures.c +++ b/openair3/S1AP/s1ap_eNB_management_procedures.c @@ -95,23 +95,43 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME( { struct s1ap_eNB_mme_data_s temp; struct s1ap_eNB_mme_data_s *found; + struct s1ap_eNB_mme_data_s *mme_p; memset(&temp, 0, sizeof(struct s1ap_eNB_mme_data_s)); temp.assoc_id = assoc_id; temp.cnx_id = cnx_id; - if (instance_p == NULL) { - STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, - s1ap_eNB_entries) { - found = RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); + if( cnx_id != 0 ) { + if (instance_p == NULL) { + STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, + s1ap_eNB_entries) { + found = RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); - if (found != NULL) { - return found; + if (found != NULL) { + return found; + } } + } else { + return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); } } else { - return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); + if (instance_p == NULL) { + STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, + s1ap_eNB_entries) { + RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + if( mme_p->assoc_id == assoc_id ) { + return mme_p; + } + } + } + } else { + RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + if( mme_p->assoc_id == assoc_id ) { + return mme_p; + } + } + } } return NULL; diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index 919989897a..b55bc06e11 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -138,8 +138,8 @@ int s1ap_eNB_handle_nas_first_req( * identity, selects the MME with the highest capacity. */ mme_desc_p = s1ap_eNB_nnsf_select_mme( - instance_p, - s1ap_nas_first_req_p->establishment_cause); + instance_p, + s1ap_nas_first_req_p->establishment_cause); if (mme_desc_p) { S1AP_INFO("[eNB %ld] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", @@ -358,10 +358,18 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, container = &pdu->choice.initiatingMessage.value.choice.DownlinkNASTransport; S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); + if(ie == NULL) + { + return -1; + } mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); + if(ie == NULL) + { + return -1; + } enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance, @@ -416,6 +424,10 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_NAS_PDU, true); + if(ie == NULL) + { + return -1; + } /* Forward the NAS PDU to RRC */ s1ap_eNB_itti_send_nas_downlink_ind(s1ap_eNB_instance->instance, ue_desc_p->ue_initial_id, @@ -494,9 +506,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ ie->criticality = S1AP_Criticality_ignore; ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI; MCC_MNC_TO_PLMNID( - s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity], - s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity], - s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mcc[ue_context_p->mme_ref->broadcast_plmn_index[0]], + s1ap_eNB_instance_p->mnc[ue_context_p->mme_ref->broadcast_plmn_index[0]], + s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->mme_ref->broadcast_plmn_index[0]], &ie->value.choice.EUTRAN_CGI.pLMNidentity); //#warning "TODO get cell id from RRC" MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id, diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c index 6319f6e054..a5a4e74734 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.c +++ b/openair3/S1AP/s1ap_eNB_nnsf.c @@ -36,15 +36,29 @@ #include "s1ap_eNB_defs.h" #include "s1ap_eNB_nnsf.h" + +typedef struct MME_nnsf_inf { + struct s1ap_eNB_mme_data_s *mme_p; + uint64_t weight; +} MME_nnsf_inf_t; + struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause) { struct s1ap_eNB_mme_data_s *mme_data_p = NULL; struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; - uint8_t current_capacity = 0; - + + uint16_t capacity_sum = 0; + MME_nnsf_inf_t mme_inf[10]; + int cnt; + int nb_mme = 0; + uint64_t weight = 0; + + memset(mme_inf, 0, sizeof(mme_inf)); + RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + capacity_sum = capacity_sum + mme_data_p->relative_mme_capacity; if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) { /* The association between MME and eNB is not ready for the moment, * go to the next known MME. @@ -69,7 +83,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) { continue; } - + mme_inf[nb_mme].mme_p = mme_data_p; + nb_mme++; /* At this point, the RRC establishment can be handled by the MME * even if it is in overload state. */ @@ -78,14 +93,27 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, continue; } } - - if (current_capacity < mme_data_p->relative_mme_capacity) { - /* We find a better MME, keep a reference to it */ - current_capacity = mme_data_p->relative_mme_capacity; - mme_highest_capacity_p = mme_data_p; - } } - + + if( nb_mme != 0 ) { + for( cnt = 0 ; cnt < nb_mme ; cnt++ ) { + mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity; + mme_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1); + } + mme_highest_capacity_p = mme_inf[0].mme_p; + weight = mme_inf[0].weight; + for( cnt = 1 ; cnt < nb_mme ; cnt++ ) { + if( weight > mme_inf[cnt].weight ) { + mme_highest_capacity_p = mme_inf[cnt].mme_p; + weight = mme_inf[cnt].weight; + } + } + } else { + mme_highest_capacity_p = NULL; + } + if( mme_highest_capacity_p != NULL ) { + mme_highest_capacity_p->nb_calls++; + } return mme_highest_capacity_p; } @@ -96,8 +124,15 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, { struct s1ap_eNB_mme_data_s *mme_data_p = NULL; struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; - uint8_t current_capacity = 0; - + + uint16_t capacity_sum = 0; + MME_nnsf_inf_t mme_inf[10]; + int cnt; + int nb_mme = 0; + uint64_t weight = 0; + + memset(mme_inf, 0, sizeof(mme_inf)); + RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { struct served_gummei_s *gummei_p = NULL; struct plmn_identity_s *served_plmn_p = NULL; @@ -140,6 +175,8 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, STAILQ_FOREACH(served_plmn_p, &gummei_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])) { + mme_inf[nb_mme].mme_p = mme_data_p; + nb_mme++; break; } } @@ -148,14 +185,27 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, } /* if we didn't find such a served PLMN, go on with the next MME */ if (!served_plmn_p) continue; - - if (current_capacity < mme_data_p->relative_mme_capacity) { - /* We find a better MME, keep a reference to it */ - current_capacity = mme_data_p->relative_mme_capacity; - mme_highest_capacity_p = mme_data_p; - } } + if( nb_mme != 0 ) { + for( cnt = 0 ; cnt < nb_mme ; cnt++ ) { + mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity; + mme_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1); + } + mme_highest_capacity_p = mme_inf[0].mme_p; + weight = mme_inf[0].weight; + for( cnt = 1 ; cnt < nb_mme ; cnt++ ) { + if( weight > mme_inf[cnt].weight ) { + mme_highest_capacity_p = mme_inf[cnt].mme_p; + weight = mme_inf[cnt].weight; + } + } + } else { + mme_highest_capacity_p = NULL; + } + if( mme_highest_capacity_p != NULL ) { + mme_highest_capacity_p->nb_calls++; + } return mme_highest_capacity_p; } diff --git a/openair3/S1AP/s1ap_eNB_overload.c b/openair3/S1AP/s1ap_eNB_overload.c index 9358ae62bd..64d3fcdf65 100644 --- a/openair3/S1AP/s1ap_eNB_overload.c +++ b/openair3/S1AP/s1ap_eNB_overload.c @@ -62,8 +62,16 @@ int s1ap_eNB_handle_overload_start(uint32_t assoc_id, S1AP_OverloadResponse_PR_overloadAction, S1AP_OverloadResponse_PR_overloadAction, 0, 0); } + else + { + return -1; + } /* Non UE-associated signalling -> stream 0 */ - DevCheck(stream == 0, stream, 0, 0); + if (stream != 0) { + S1AP_ERROR("[SCTP %d] Received s1 overload start on stream != 0 (%d)\n", + assoc_id, stream); + return -1; + } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { /* No MME context associated */ @@ -93,7 +101,11 @@ int s1ap_eNB_handle_overload_stop(uint32_t assoc_id, s1ap_eNB_mme_data_t *mme_desc_p; /* Non UE-associated signalling -> stream 0 */ - DevCheck(stream == 0, stream, 0, 0); + if (stream != 0) { + S1AP_ERROR("[SCTP %d] Received s1 overload stop on stream != 0 (%d)\n", + assoc_id, stream); + return -1; + } if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { /* No MME context associated */ diff --git a/openair3/S1AP/s1ap_eNB_trace.c b/openair3/S1AP/s1ap_eNB_trace.c index 19f5059238..695eeb4ef8 100644 --- a/openair3/S1AP/s1ap_eNB_trace.c +++ b/openair3/S1AP/s1ap_eNB_trace.c @@ -121,6 +121,10 @@ int s1ap_eNB_handle_trace_start(uint32_t assoc_id, if (ie != NULL) { ue_desc_p = s1ap_eNB_get_ue_context(mme_ref_p->s1ap_eNB_instance, ie->value.choice.ENB_UE_S1AP_ID); + } + else + { + return -1; } if (ue_desc_p == NULL) { /* Could not find context associated with this eNB_ue_s1ap_id -> generate diff --git a/openair3/SCTP/sctp_default_values.h b/openair3/SCTP/sctp_default_values.h index 528ffb5a05..0f8f94dca9 100644 --- a/openair3/SCTP/sctp_default_values.h +++ b/openair3/SCTP/sctp_default_values.h @@ -24,8 +24,8 @@ #define SCTP_OUT_STREAMS (16) #define SCTP_IN_STREAMS (16) -#define SCTP_MAX_ATTEMPTS (2) -#define SCTP_TIMEOUT (5) +#define SCTP_MAX_ATTEMPTS (8) +#define SCTP_TIMEOUT (60000) #define SCTP_RECV_BUFFER_SIZE (8192) #endif /* SCTP_DEFAULT_VALUES_H_ */ diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 2f732443be..af49c5c350 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -270,7 +270,7 @@ sctp_handle_new_association_req_multi( sctp_new_association_req_p->remote_address.ipv6_address); //close(sd); //return; - exit(1); + exit_fun("sctp_handle_new_association_req_multi fatal: inet_pton error"); } SCTP_DEBUG("Converted ipv6 address %*s to network type\n", @@ -290,7 +290,7 @@ sctp_handle_new_association_req_multi( sctp_new_association_req_p->remote_address.ipv4_address); //close(sd); //return; - exit(1); + exit_fun("sctp_handle_new_association_req_multi fatal: inet_pton error"); } SCTP_DEBUG("Converted ipv4 address %*s to network type\n", @@ -329,7 +329,7 @@ sctp_handle_new_association_req_multi( if (ns == -1) { perror("sctp_peeloff"); printf("sctp_peeloff: sd=%d assoc_id=%d\n", sd, assoc_id); - exit(1); + exit_fun("sctp_handle_new_association_req_multi fatal: sctp_peeloff error"); } sctp_cnx = calloc(1, sizeof(*sctp_cnx)); @@ -943,10 +943,12 @@ sctp_eNB_read_from_socket( &sinfo, &flags); if (n < 0) { - if (errno == ENOTCONN) { + if( (errno == ENOTCONN) || (errno == ECONNRESET) || (errno == ETIMEDOUT) || (errno == ECONNREFUSED) ) + { itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd); SCTP_DEBUG("Received not connected for sd %d\n", sctp_cnx->sd); + SCTP_ERROR("sctp_recvmsg (fd %d, len %d ): %s:%d\n", sctp_cnx->sd, n, strerror(errno), errno); sctp_itti_send_association_resp( sctp_cnx->task_id, sctp_cnx->instance, -1, @@ -969,7 +971,7 @@ sctp_eNB_read_from_socket( if (!(flags & MSG_EOR)) { SCTP_ERROR("fatal: partial SCTP messages are not handled\n"); - exit(1); + exit_fun("fatal: partial SCTP messages are not handled" ); } if (flags & MSG_NOTIFICATION) { diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 85ee80ea7c..93e9ffb52f 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -105,9 +105,10 @@ typedef enum { ADRV9371_ZC706_DEV, /*!\brief device is UEDv2 */ UEDv2_DEV, + RFSIMULATOR, MAX_RF_DEV_TYPE } dev_type_t; -#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2"} +#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2", "RFSIMULATOR"} /*!\brief transport protocol types */ typedef enum { @@ -491,15 +492,11 @@ struct openair0_device_t { typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg); /* type of transport init function, implemented in shared lib */ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params); -#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record -#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record -#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record -#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record +#define UE_MAGICDL 0xA5A5A5A5A5A5A5A5 // UE DL FDD record +#define UE_MAGICUL 0x5A5A5A5A5A5A5A5A // UE UL FDD record -#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record -#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record -#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record -#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record +#define ENB_MAGICDL 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record +#define ENB_MAGICUL 0x5B5B5B5B5B5B5B5B // eNB UL FDD record #define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) @@ -516,19 +513,6 @@ typedef struct { uint32_t option_flag; // Option flag } samplesBlockHeader_t; -#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record -#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record -#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record -#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record - -#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record -#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record -#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record -#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record - -#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) - - #ifdef __cplusplus extern "C" { diff --git a/targets/ARCH/ETHERNET/benetel/4g/benetel.c b/targets/ARCH/ETHERNET/benetel/4g/benetel.c index 76855111e1..d3b72463b4 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/4g/benetel.c @@ -163,8 +163,8 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) cap->FH_fmt = OAI_IF4p5_only; cap->num_bands = 1; cap->band_list[0] = 7; - cap->nb_rx[0] = 1; - cap->nb_tx[0] = 1; + cap->nb_rx[0] = device->openair0_cfg->rx_num_channels; + cap->nb_tx[0] = device->openair0_cfg->tx_num_channels; cap->max_pdschReferenceSignalPower[0] = -27; cap->max_rxgain[0] = 90; @@ -194,11 +194,12 @@ void benetel_fh_if4p5_south_in(RU_t *ru, LTE_DL_FRAME_PARMS *fp; int symbol; int32_t *rxdata; - int antenna = 0; + int antenna; lock_ul_buffer(&s->buffers, *subframe); next: - while (!(s->buffers.ul_busy[*subframe] == 0x3fff || + while (!((s->buffers.ul_busy[0][*subframe] == 0x3fff && + s->buffers.ul_busy[1][*subframe] == 0x3fff) || s->buffers.prach_busy[*subframe] == 1)) wait_ul_buffer(&s->buffers, *subframe); if (s->buffers.prach_busy[*subframe] == 1) { @@ -217,24 +218,27 @@ next: eNB = eNB_list[0]; fp = &eNB->frame_parms; - for (symbol = 0; symbol < 14; symbol++) { - int i; - uint16_t *p = (uint16_t *)(&s->buffers.ul[*subframe][symbol*1200*4]); - for (i = 0; i < 1200*2; i++) { - p[i] = htons(p[i]); - } - rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; + for (antenna = 0; antenna < ru->nb_rx; antenna++) { + for (symbol = 0; symbol < 14; symbol++) { + int i; + uint16_t *p = (uint16_t *)(&s->buffers.ul[antenna][*subframe][symbol*1200*4]); + for (i = 0; i < 1200*2; i++) { + p[i] = htons(p[i]); + } + rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(rxdata + 2048 - 600, - &s->buffers.ul[*subframe][symbol*1200*4], - 600 * 4); - memcpy(rxdata, - &s->buffers.ul[*subframe][symbol*1200*4] + 600*4, - 600 * 4); + memcpy(rxdata + 2048 - 600, + &s->buffers.ul[antenna][*subframe][symbol*1200*4], + 600 * 4); + memcpy(rxdata, + &s->buffers.ul[antenna][*subframe][symbol*1200*4] + 600*4, + 600 * 4); #endif + } } - s->buffers.ul_busy[*subframe] = 0; + s->buffers.ul_busy[0][*subframe] = 0; + s->buffers.ul_busy[1][*subframe] = 0; signal_ul_buffer(&s->buffers, *subframe); unlock_ul_buffer(&s->buffers, *subframe); @@ -272,45 +276,49 @@ void benetel_fh_if4p5_south_out(RU_t *ru, LTE_DL_FRAME_PARMS *fp; int symbol; int32_t *txdata; - int aa = 0; + int aa; //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); lock_dl_buffer(&s->buffers, subframe); - if (s->buffers.dl_busy[subframe]) { + if (s->buffers.dl_busy[0][subframe] || + s->buffers.dl_busy[1][subframe]) { printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, subframe); unlock_dl_buffer(&s->buffers, subframe); return; } eNB = eNB_list[0]; fp = &eNB->frame_parms; - if (ru->num_eNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 || + if (ru->num_eNB != 1 || fp->ofdm_symbol_size != 2048 || fp->Ncp != NORMAL || fp->symbols_per_tti != 14) { printf("%s:%d:%s: unsupported configuration\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - for (symbol = 0; symbol < 14; symbol++) { - txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; + for (aa = 0; aa < ru->nb_tx; aa++) { + for (symbol = 0; symbol < 14; symbol++) { + txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(&s->buffers.dl[subframe][symbol*1200*4], - txdata + 2048 - 600, - 600 * 4); - memcpy(&s->buffers.dl[subframe][symbol*1200*4] + 600*4, - txdata + 1, - 600 * 4); + memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4], + txdata + 2048 - 600, + 600 * 4); + memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4] + 600*4, + txdata + 1, + 600 * 4); #endif - int i; - uint16_t *p = (uint16_t *)(&s->buffers.dl[subframe][symbol*1200*4]); - for (i = 0; i < 1200*2; i++) { - p[i] = htons(p[i]); + int i; + uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][subframe][symbol*1200*4]); + for (i = 0; i < 1200*2; i++) { + p[i] = htons(p[i]); + } } } - s->buffers.dl_busy[subframe] = 0x3fff; + s->buffers.dl_busy[0][subframe] = 0x3fff; + s->buffers.dl_busy[1][subframe] = 0x3fff; unlock_dl_buffer(&s->buffers, subframe); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx); diff --git a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c index 42953d1d4a..2b6ef37e6f 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c @@ -233,19 +233,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00) { + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce) { p.frame = FRAME; p.subframe = SUBFRAME >> 4; p.slot = 0; /* unused */ p.symbol = SYMBOL; - p.antenna = 0; + p.antenna = ANT_NUM; memcpy(p.iq, IQ_ptr, 4800); store_ul(bs, &p); } - // U-PLANE UL ANT_0 PROCESSING - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00 && dl_start == 1) + // U-PLANE UL PROCESSING + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && dl_start == 1) { + int a = ANT_NUM; int tx_frame = FRAME; int tx_subframe = SUBFRAME >> 4; int tx_symbol = SYMBOL + 5; @@ -266,33 +267,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) SUBFRAME = tx_subframe << 4; SYMBOL = tx_symbol; - /* antenna 0 - send actual DL data (if available) */ + /* send actual DL data (if available) */ lock_dl_buffer(bs->buffers, tx_subframe); - if (!(bs->buffers->dl_busy[tx_subframe] & (1 << tx_symbol))) { - printf("%s: warning, DL underflow (sf.symbol %d.%d)\n", __FUNCTION__, + if (!(bs->buffers->dl_busy[a][tx_subframe] & (1 << tx_symbol))) { + printf("%s: warning, DL underflow (antenna %d sf.symbol %d.%d)\n", + __FUNCTION__, + a, tx_subframe, tx_symbol); memset(IQ_ptr, 0, 1200 * 4); } else { - memcpy(IQ_ptr, bs->buffers->dl[tx_subframe] + tx_symbol * 1200*4, + memcpy(IQ_ptr, bs->buffers->dl[a][tx_subframe] + tx_symbol * 1200*4, 1200*4); } - bs->buffers->dl_busy[tx_subframe] &= ~(1 << tx_symbol); + bs->buffers->dl_busy[a][tx_subframe] &= ~(1 << tx_symbol); unlock_dl_buffer(bs->buffers, tx_subframe); - - // fill DL Data for ant 0 with 0 value -// memset(IQ_ptr, 0, 4800); - } - - // U-PLANE UL ANT_1 PROCESSING - else if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x01 && dl_start == 1) - { - -// ANT_NUM = 0x01; - SYMBOL = (SYMBOL + 5) % 14; - PAYLOAD_2 = 0xc8; - - // fill DL Data for ant 1 with 0 value - memset(IQ_ptr, 0, 4800); } // U-PLANE PRACH PROCESSING diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.c b/targets/ARCH/ETHERNET/benetel/4g/low.c index 038592d596..14783a700b 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low.c +++ b/targets/ARCH/ETHERNET/benetel/4g/low.c @@ -27,37 +27,36 @@ void store_ul(benetel_t *bs, ul_packet_t *ul) { - /* only antenna 0 for the moment */ - if (ul->antenna != 0) - return; + int a = ul->antenna; - if (ul->subframe != bs->next_subframe || - ul->symbol != bs->next_symbol) { - printf("%s: fatal, expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n", + if (ul->subframe != bs->next_subframe[a] || + ul->symbol != bs->next_symbol[a]) { + printf("%s: fatal, antenna %d expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n", __FUNCTION__, - bs->expected_benetel_frame, bs->next_subframe, bs->next_symbol, + a, + bs->expected_benetel_frame[a], bs->next_subframe[a], bs->next_symbol[a], ul->frame, ul->subframe, ul->symbol); exit(1); } - lock_ul_buffer(bs->buffers, bs->next_subframe); - if (bs->buffers->ul_busy[bs->next_subframe] & (1 << bs->next_symbol)) { + lock_ul_buffer(bs->buffers, bs->next_subframe[a]); + if (bs->buffers->ul_busy[a][bs->next_subframe[a]] & (1 << bs->next_symbol[a])) { printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__, - bs->next_subframe, bs->next_symbol); + bs->next_subframe[a], bs->next_symbol[a]); } - memcpy(bs->buffers->ul[bs->next_subframe] + bs->next_symbol * 1200*4, + memcpy(bs->buffers->ul[a][bs->next_subframe[a]] + bs->next_symbol[a] * 1200*4, ul->iq, 1200*4); - bs->buffers->ul_busy[bs->next_subframe] |= (1 << bs->next_symbol); - signal_ul_buffer(bs->buffers, bs->next_subframe); - unlock_ul_buffer(bs->buffers, bs->next_subframe); + bs->buffers->ul_busy[a][bs->next_subframe[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_subframe[a]); + unlock_ul_buffer(bs->buffers, bs->next_subframe[a]); - bs->next_symbol++; - if (bs->next_symbol == 14) { - bs->next_symbol = 0; - bs->next_subframe = (bs->next_subframe + 1) % 10; - if (bs->next_subframe == 0) { - bs->expected_benetel_frame++; - bs->expected_benetel_frame &= 255; + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_subframe[a] = (bs->next_subframe[a] + 1) % 10; + if (bs->next_subframe[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.h b/targets/ARCH/ETHERNET/benetel/4g/low.h index 5e75d9181e..e74bf89163 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low.h +++ b/targets/ARCH/ETHERNET/benetel/4g/low.h @@ -26,9 +26,10 @@ typedef struct { shared_buffers *buffers; - int next_subframe; - int next_symbol; - int expected_benetel_frame; + /* [2] is for two antennas */ + int next_subframe[2]; + int next_symbol[2]; + int expected_benetel_frame[2]; char *dpdk_main_command_line; } benetel_t; diff --git a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c index ecff473010..edf62a67e0 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c +++ b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c @@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_ bs->buffers = buffers; - bs->expected_benetel_frame = 255; + bs->expected_benetel_frame[0] = 255; + bs->expected_benetel_frame[1] = 255; bs->dpdk_main_command_line = dpdk_main_command_line; diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c index 492a15dfc3..380cbabc73 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c +++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c @@ -44,9 +44,12 @@ void init_buffers(shared_buffers *s) /* in FDD the eNB's first transmitted DL subframe is 4 but the device * needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready. */ - s->dl_busy[1] = 0x3fff; - s->dl_busy[2] = 0x3fff; - s->dl_busy[3] = 0x3fff; + s->dl_busy[0][1] = 0x3fff; + s->dl_busy[0][2] = 0x3fff; + s->dl_busy[0][3] = 0x3fff; + s->dl_busy[1][1] = 0x3fff; + s->dl_busy[1][2] = 0x3fff; + s->dl_busy[1][3] = 0x3fff; } void lock_dl_buffer(shared_buffers *s, int subframe) diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h index 1d5040b95b..ed174265c5 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h +++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h @@ -26,10 +26,11 @@ #include typedef struct { - unsigned char dl[10][14*1200*4]; - unsigned char ul[10][14*1200*4]; - uint16_t dl_busy[10]; - uint16_t ul_busy[10]; + /* [2] is for two antennas */ + unsigned char dl[2][10][14*1200*4]; + unsigned char ul[2][10][14*1200*4]; + uint16_t dl_busy[2][10]; + uint16_t ul_busy[2][10]; pthread_mutex_t m_ul[10]; pthread_cond_t c_ul[10]; diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index 2f60e7dc49..cededa968e 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -162,8 +162,9 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) cap->FH_fmt = OAI_IF4p5_only; cap->num_bands = 1; cap->band_list[0] = 78; - cap->nb_rx[0] = 1; - cap->nb_tx[0] = 1; + /* TODO: hardcoded to 1 for the moment, get the real value somehow... */ + cap->nb_rx[0] = 1; //device->openair0_cfg->rx_num_channels; + cap->nb_tx[0] = 1; //device->openair0_cfg->tx_num_channels; cap->max_pdschReferenceSignalPower[0] = -27; cap->max_rxgain[0] = 90; @@ -201,12 +202,13 @@ void benetel_fh_if4p5_south_in(RU_t *ru, NR_DL_FRAME_PARMS *fp; int symbol; int32_t *rxdata; - int antenna = 0; + int antenna; lock_ul_buffer(&s->buffers, *slot); #if 1 next: - while (!(s->buffers.ul_busy[*slot] == 0x3fff || + while (!((s->buffers.ul_busy[0][*slot] == 0x3fff && + s->buffers.ul_busy[1][*slot] == 0x3fff) || s->buffers.prach_busy[*slot] == 1)) wait_ul_buffer(&s->buffers, *slot); if (s->buffers.prach_busy[*slot] == 1) { @@ -226,24 +228,31 @@ next: #endif fp = ru->nr_frame_parms; - for (symbol = 0; symbol < 14; symbol++) { - int i; - uint16_t *p = (uint16_t *)(&s->buffers.ul[*slot][symbol*1272*4]); - for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]); - } - rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; -#if 1 - memcpy(rxdata + 2048 - 1272/2, - &s->buffers.ul[*slot][symbol*1272*4], - (1272/2) * 4); - memcpy(rxdata, - &s->buffers.ul[*slot][symbol*1272*4] + (1272/2)*4, - (1272/2) * 4); + for (antenna = 0; antenna < ru->nb_rx; antenna++) { + for (symbol = 0; symbol < 14; symbol++) { + int i; + int16_t *p = (int16_t *)(&s->buffers.ul[antenna][*slot][symbol*1272*4]); + for (i = 0; i < 1272*2; i++) { + p[i] = (int16_t)(ntohs(p[i])) / 16; + } + rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; +#if 0 +if (*slot == 0 && symbol == 0) +printf("rxdata in benetel_fh_if4p5_south_in %p\n", &ru->common.rxdataF[antenna][0]); #endif +#if 1 + memcpy(rxdata + 2048 - 1272/2, + &s->buffers.ul[antenna][*slot][symbol*1272*4], + (1272/2) * 4); + memcpy(rxdata, + &s->buffers.ul[antenna][*slot][symbol*1272*4] + (1272/2)*4, + (1272/2) * 4); +#endif + } } - s->buffers.ul_busy[*slot] = 0; + s->buffers.ul_busy[0][*slot] = 0; + s->buffers.ul_busy[1][*slot] = 0; signal_ul_buffer(&s->buffers, *slot); unlock_ul_buffer(&s->buffers, *slot); @@ -281,43 +290,47 @@ void benetel_fh_if4p5_south_out(RU_t *ru, NR_DL_FRAME_PARMS *fp; int symbol; int32_t *txdata; - int aa = 0; + int aa; //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, slot, timestamp); lock_dl_buffer(&s->buffers, slot); - if (s->buffers.dl_busy[slot]) { + if (s->buffers.dl_busy[0][slot] || + s->buffers.dl_busy[1][slot]) { printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, slot); unlock_dl_buffer(&s->buffers, slot); return; } fp = ru->nr_frame_parms; - if (ru->num_gNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 || + if (ru->num_gNB != 1 || fp->ofdm_symbol_size != 2048 || fp->Ncp != NORMAL || fp->symbols_per_slot != 14) { printf("%s:%d:%s: unsupported configuration\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - for (symbol = 0; symbol < 14; symbol++) { - txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; + for (aa = 0; aa < ru->nb_tx; aa++) { + for (symbol = 0; symbol < 14; symbol++) { + txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; #if 1 - memcpy(&s->buffers.dl[slot][symbol*1272*4], - txdata + 2048 - (1272/2), - (1272/2) * 4); - memcpy(&s->buffers.dl[slot][symbol*1272*4] + (1272/2)*4, - txdata, - (1272/2) * 4); + memcpy(&s->buffers.dl[aa][slot][symbol*1272*4], + txdata + 2048 - (1272/2), + (1272/2) * 4); + memcpy(&s->buffers.dl[aa][slot][symbol*1272*4] + (1272/2)*4, + txdata, + (1272/2) * 4); #endif - int i; - uint16_t *p = (uint16_t *)(&s->buffers.dl[slot][symbol*1272*4]); - for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]); + int i; + uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][slot][symbol*1272*4]); + for (i = 0; i < 1272*2; i++) { + p[i] = htons(p[i]); + } } } - s->buffers.dl_busy[slot] = 0x3fff; + s->buffers.dl_busy[0][slot] = 0x3fff; + s->buffers.dl_busy[1][slot] = 0x3fff; unlock_dl_buffer(&s->buffers, slot); } diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c index dd50603ec5..9b398e9bd9 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c @@ -243,21 +243,22 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00) { + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4) { int subframe = SUBFRAME >> 4; int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); p.frame = FRAME; p.slot = subframe * 2 + slot; p.symbol = SYMBOL & 0x3f; - p.antenna = 0; + p.antenna = ANT_NUM; 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); } - // U-PLANE UL ANT_0 PROCESSING - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00 && dl_start == 1) + // U-PLANE UL PROCESSING + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && dl_start == 1) { + int a = ANT_NUM & 0x01; int frame = FRAME; int subframe = SUBFRAME >> 4; int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); @@ -282,66 +283,44 @@ 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) + 10) % 14; - ANT_NUM = 0x00; + ANT_NUM = a; SUBFRAME = sf; + if (a == 1) + slot_id_ctrl++; + // Slot id control for DL - if(slot_id_ctrl > 13){ - SYMBOL = SYMBOL | 0b01000000; + if (slot_id_ctrl > 13) { + SYMBOL = SYMBOL | 0b01000000; + + if (a == 1) { + if (slot_id_ctrl > 27) { + slot_id_ctrl = 0; + sf = sf + 0x10; + + if (sf > 0x90){ + sf = 0; + } + } + } } - /* antenna 0 - send actual DL data (if available) */ + /* send actual DL data (if available) */ oai_slot = tx_subframe * 2 + tx_slot; lock_dl_buffer(bs->buffers, oai_slot); - if (!(bs->buffers->dl_busy[oai_slot] & (1 << tx_symbol))) { - printf("%s: warning, DL underflow (sl.symbol %d.%d)\n", __FUNCTION__, - oai_slot, tx_symbol); + if (!(bs->buffers->dl_busy[a][oai_slot] & (1 << tx_symbol))) { + //printf("%s: warning, DL underflow (antenna %d sl.symbol %d.%d)\n", __FUNCTION__,a, oai_slot, tx_symbol); memset(IQ_ptr, 0, 1272 * 4); } else { - memcpy(IQ_ptr, bs->buffers->dl[oai_slot] + tx_symbol * 1272*4, + memcpy(IQ_ptr, bs->buffers->dl[a][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); + //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[a][oai_slot] &= ~(1 << tx_symbol); unlock_dl_buffer(bs->buffers, oai_slot); - - // fill DL Data for ant 0 with 0 value -// memset(IQ_ptr, 0, 5088); - } - - // U-PLANE UL ANT_1 PROCESSING - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x01 && dl_start == 1) - { - - // Mask the symbol bits from UL packet received and apply the shift. - SYMBOL = ((SYMBOL & 0b00111111) +10) % 14; - - ANT_NUM = 0x01; - SUBFRAME = sf; - - slot_id_ctrl++; - - // Slot id control for DL - if(slot_id_ctrl > 13){ - SYMBOL = SYMBOL | 0b01000000; - - if(slot_id_ctrl > 27){ - slot_id_ctrl = 0; - sf = sf + 0x10; - - if (sf >0x90){ - sf = 0; - } - } - } - - // fill DL Data for ant 1 with 0 value - memset(IQ_ptr, 0, 5088); } // U-PLANE PRACH PROCESSING diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.c b/targets/ARCH/ETHERNET/benetel/5g/low.c index 52c9f24127..b34d69784f 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low.c +++ b/targets/ARCH/ETHERNET/benetel/5g/low.c @@ -35,63 +35,61 @@ printf("store_ul %d.%ld (%ld)\n", (int)(t.tv_sec % 60), t.tv_nsec, t.tv_nsec - o old = t; #endif - /* only antenna 0 for the moment */ - if (ul->antenna != 0) - return; + int a = ul->antenna; - if (ul->slot != bs->next_slot || - ul->symbol != bs->next_symbol) { - printf("%s: error, expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", + if (ul->slot != bs->next_slot[a] || + ul->symbol != bs->next_symbol[a]) { + printf("%s: error, antenna %d expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", __FUNCTION__, - bs->expected_benetel_frame, bs->next_slot, bs->next_symbol, + a, bs->expected_benetel_frame[a], bs->next_slot[a], bs->next_symbol[a], ul->frame, ul->slot, ul->symbol); } /* 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); + while (ul->slot != bs->next_slot[a] || + ul->symbol != bs->next_symbol[a]) { + lock_ul_buffer(bs->buffers, bs->next_slot[a]); + if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) { + printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + a, bs->next_slot[a], bs->next_symbol[a]); } - memset(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + memset(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 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->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_slot[a]); + unlock_ul_buffer(bs->buffers, bs->next_slot[a]); - 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; + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_slot[a] = (bs->next_slot[a] + 1) % 20; + if (bs->next_slot[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } - 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); + lock_ul_buffer(bs->buffers, bs->next_slot[a]); + if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) { + printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + a, bs->next_slot[a], bs->next_symbol[a]); } - memcpy(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + memcpy(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4, ul->iq, 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->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]); + signal_ul_buffer(bs->buffers, bs->next_slot[a]); + unlock_ul_buffer(bs->buffers, bs->next_slot[a]); - 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; + bs->next_symbol[a]++; + if (bs->next_symbol[a] == 14) { + bs->next_symbol[a] = 0; + bs->next_slot[a] = (bs->next_slot[a] + 1) % 20; + if (bs->next_slot[a] == 0) { + bs->expected_benetel_frame[a]++; + bs->expected_benetel_frame[a] &= 255; } } } diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.h b/targets/ARCH/ETHERNET/benetel/5g/low.h index 5e1daee9d1..659819296a 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low.h +++ b/targets/ARCH/ETHERNET/benetel/5g/low.h @@ -26,9 +26,10 @@ typedef struct { shared_buffers *buffers; - int next_slot; - int next_symbol; - int expected_benetel_frame; + /* [2] is for two antennas */ + int next_slot[2]; + int next_symbol[2]; + int expected_benetel_frame[2]; char *dpdk_main_command_line; } benetel_t; diff --git a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c index 5e26f6782e..b26df07723 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c +++ b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c @@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_ bs->buffers = buffers; - bs->expected_benetel_frame = 255; + bs->expected_benetel_frame[0] = 255; + bs->expected_benetel_frame[1] = 255; bs->dpdk_main_command_line = dpdk_main_command_line; diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c index b9da10b380..a302400eb4 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c +++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c @@ -45,11 +45,16 @@ void init_buffers(shared_buffers *s) * needs to have slots 1, 2 and 3, 4 and 5 ready. Let's pretend * they are ready. */ - s->dl_busy[1] = 0x3fff; - s->dl_busy[2] = 0x3fff; - s->dl_busy[3] = 0x3fff; - s->dl_busy[4] = 0x3fff; - s->dl_busy[5] = 0x3fff; + s->dl_busy[0][1] = 0x3fff; + s->dl_busy[0][2] = 0x3fff; + s->dl_busy[0][3] = 0x3fff; + s->dl_busy[0][4] = 0x3fff; + s->dl_busy[0][5] = 0x3fff; + s->dl_busy[1][1] = 0x3fff; + s->dl_busy[1][2] = 0x3fff; + s->dl_busy[1][3] = 0x3fff; + s->dl_busy[1][4] = 0x3fff; + s->dl_busy[1][5] = 0x3fff; } void lock_dl_buffer(shared_buffers *s, int slot) diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h index ca7dbd9c8f..9d51b8138d 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h +++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h @@ -26,10 +26,11 @@ #include typedef struct { - unsigned char dl[20][14*1272*4]; - unsigned char ul[20][14*1272*4]; - uint16_t dl_busy[20]; - uint16_t ul_busy[20]; + /* [2] is for two antennas */ + unsigned char dl[2][20][14*1272*4]; + unsigned char ul[2][20][14*1272*4]; + uint16_t dl_busy[2][20]; + uint16_t ul_busy[2][20]; pthread_mutex_t m_ul[20]; pthread_cond_t c_ul[20]; diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 851082f44b..bd69f91942 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -1110,7 +1110,7 @@ extern "C" { case 46080000: //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_sample_advance = 65; openair0_cfg[0].tx_bw = 40e6; openair0_cfg[0].rx_bw = 40e6; break; @@ -1125,7 +1125,7 @@ extern "C" { case 15360000: //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 45; + openair0_cfg[0].tx_sample_advance = 40; openair0_cfg[0].tx_bw = 10e6; openair0_cfg[0].rx_bw = 10e6; break; diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c index c4133d1b11..66308d4b1c 100644 --- a/targets/ARCH/iqplayer/iqplayer_lib.c +++ b/targets/ARCH/iqplayer/iqplayer_lib.c @@ -25,7 +25,6 @@ */ #define _LARGEFILE_SOURCE #define _FILE_OFFSET_BITS 64 -#define NB_ANTENNAS_RX 2 #include #include #include diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 79bf3dd077..96d9541db9 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -54,7 +54,7 @@ #include #define PORT 4043 //default TCP port for this simulator -#define CirSize 307200 // 100ms is enough +#define CirSize 6144000 // 100ms is enough #define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t)) #define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b))) @@ -76,15 +76,16 @@ extern RAN_CONTEXT_t RC; /* configuration parameters for the rfsimulator device */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define RFSIMULATOR_PARAMS_DESC {\ - {"serveraddr", "\n", 0, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ - {"serverport", "\n", 0, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ - {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\ - {"IQfile", "\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ - {"modelname", "\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\ - {"ploss", "\n", 0, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\ - {"forgetfact", "\n", 0, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\ - {"offset", "\n", 0, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\ +#define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED +#define RFSIMULATOR_PARAMS_DESC { \ + {"serveraddr", "\n", simOpt , strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ + {"serverport", "\n", simOpt, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ + {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\ + {"IQfile", "\n",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ + {"modelname", "\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\ + {"ploss", "\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\ + {"forgetfact", "\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\ + {"offset", "\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\ }; @@ -137,7 +138,7 @@ typedef struct { } rfsimulator_state_t; -void allocCirBuf(rfsimulator_state_t *bridge, int sock) { +static void allocCirBuf(rfsimulator_state_t *bridge, int sock) { buffer_t *ptr=&bridge->buf[sock]; AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, ""); ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1); @@ -195,7 +196,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { } } -void removeCirBuf(rfsimulator_state_t *bridge, int sock) { +static void removeCirBuf(rfsimulator_state_t *bridge, int sock) { AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, ""); close(sock); free(bridge->buf[sock].circularBuf); @@ -206,12 +207,12 @@ void removeCirBuf(rfsimulator_state_t *bridge, int sock) { bridge->buf[sock].conn_sock=-1; } -void socketError(rfsimulator_state_t *bridge, int sock) { +static void socketError(rfsimulator_state_t *bridge, int sock) { if (bridge->buf[sock].conn_sock!=-1) { LOG_W(HW,"Lost socket \n"); removeCirBuf(bridge, sock); - if (bridge->typeStamp==UE_MAGICDL_FDD) + if (bridge->typeStamp==UE_MAGICDL) exit(1); } } @@ -229,7 +230,7 @@ enum blocking_t { blocking }; -void setblocking(int sock, enum blocking_t active) { +static void setblocking(int sock, enum blocking_t active) { int opts; AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,""); @@ -243,7 +244,7 @@ void setblocking(int sock, enum blocking_t active) { static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps); -void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { +static void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { if (t->saveIQfile != -1) { if (write(t->saveIQfile, _buf, count) != count ) LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno)); @@ -277,7 +278,7 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { } } -void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { +static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { char *saveF=NULL; char *modelname=NULL; paramdef_t rfsimu_params[] = RFSIMULATOR_PARAMS_DESC; @@ -312,9 +313,9 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 || strncasecmp(rfsimulator->ip,"server",3) == 0 ) - rfsimulator->typeStamp = ENB_MAGICDL_FDD; + rfsimulator->typeStamp = ENB_MAGICDL; else - rfsimulator->typeStamp = UE_MAGICDL_FDD; + rfsimulator->typeStamp = UE_MAGICDL; } static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) { @@ -358,9 +359,9 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, return CMDSTATUS_FOUND; } -int server_start(openair0_device *device) { +static int startServer(openair0_device *device) { rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; - t->typeStamp=ENB_MAGICDL_FDD; + t->typeStamp=ENB_MAGICDL; AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); int enable = 1; AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, ""); @@ -381,9 +382,9 @@ sin_addr: return 0; } -int start_ue(openair0_device *device) { +static int startClient(openair0_device *device) { rfsimulator_state_t *t = device->priv; - t->typeStamp=UE_MAGICDL_FDD; + t->typeStamp=UE_MAGICDL; int sock; AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); struct sockaddr_in addr = { @@ -458,7 +459,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp return nsamps; } -int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { +static int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { return rfsimulator_write_internal(device->priv, timestamp, samplesVoid, nsamps, nbAnt, flags, false); } @@ -483,7 +484,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, ""); setblocking(conn_sock, notBlocking); allocCirBuf(t, conn_sock); - LOG_I(HW,"A ue connected, sending the current time\n"); + LOG_I(HW,"A client connected, sending the current time\n"); struct complex16 v= {0}; void *samplesVoid[t->tx_num_channels]; @@ -534,8 +535,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi // check the header and start block transfer if ( b->headerMode==true && b->remainToTransfer==0) { - AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) || - (t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol"); + AssertFatal( (t->typeStamp == UE_MAGICDL && b->th.magic==ENB_MAGICDL) || + (t->typeStamp == ENB_MAGICDL && b->th.magic==UE_MAGICDL), "Socket Error in protocol"); b->headerMode=false; if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS @@ -606,7 +607,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi return nfds>0; } -int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { +static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { if (nbAnt != 1) { LOG_W(HW, "rfsimulator: only 1 antenna tested\n"); } @@ -748,31 +749,24 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo signal_energy(samplesVoid[0], nsamps)); return nsamps; } -int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) { - abort(); + +static int rfsimulator_get_stats(openair0_device *device) { return 0; } -int rfsimulator_reply(openair0_device *device, void *msg, ssize_t msg_len) { - abort(); +static int rfsimulator_reset_stats(openair0_device *device) { return 0; } -int rfsimulator_get_stats(openair0_device *device) { +static void rfsimulator_end(openair0_device *device) {} +static int rfsimulator_stop(openair0_device *device) { return 0; } -int rfsimulator_reset_stats(openair0_device *device) { +static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { return 0; } -void rfsimulator_end(openair0_device *device) {} -int rfsimulator_stop(openair0_device *device) { +static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { return 0; } -int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { - return 0; -} -int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { - return 0; -} -int rfsimulator_write_init(openair0_device *device) { +static int rfsimulator_write_init(openair0_device *device) { return 0; } __attribute__((__visibility__("default"))) @@ -782,10 +776,10 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); rfsimulator_readconfig(rfsimulator); pthread_mutex_init(&Sockmutex, NULL); - LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "(eg)NB" : "UE"); - device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL_FDD ? - server_start : - start_ue; + LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL ? "server waiting opposite rfsimulators to connect" : "client: will connect to a rfsimulator server side"); + device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL ? + startServer : + startClient; device->trx_get_stats_func = rfsimulator_get_stats; device->trx_reset_stats_func = rfsimulator_reset_stats; device->trx_end_func = rfsimulator_end; @@ -795,7 +789,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->trx_write_func = rfsimulator_write; device->trx_read_func = rfsimulator_read; /* let's pretend to be a b2x0 */ - device->type = USRP_B200_DEV; + device->type = RFSIMULATOR; device->openair0_cfg=&openair0_cfg[0]; device->priv = rfsimulator; device->trx_write_init = rfsimulator_write_init; diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c index daf0133af2..dcea69b9dd 100644 --- a/targets/ARCH/rfsimulator/stored_node.c +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -200,7 +200,10 @@ int main(int argc, char *argv[]) { int bufSize=100000; void *buff=malloc(bufSize); uint64_t timestamp=0; - const int blockSize=1000; + const int blockSize=1920; + + // If fileSize is not multiple of blockSize*4 then discard remaining samples + fileSize = (fileSize/(blockSize<<2))*(blockSize<<2); while (1) { //Rewind the file to loop on the samples diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf index 49b4e4441e..aab3876d96 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf @@ -230,12 +230,12 @@ RUs = ( local_if_name = "dpdk"; 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"; - local_portc = 50000; - remote_portc = 50000; - local_portd = 50001; - remote_portd = 50001; + #remote_address = "127.0.0.2"; + #local_address = "127.0.0.1"; + #local_portc = 50000; + #remote_portc = 50000; + #local_portd = 50001; + #remote_portd = 50001; local_rf = "no" tr_preference = "raw_if4p5" nb_tx = 1 diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 037de199df..a426c39a7a 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -23,6 +23,9 @@ gNBs = ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + #pusch_TargetSNRx10 = 200; + #pucch_TargetSNRx10 = 200; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; @@ -48,7 +51,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -57,27 +60,14 @@ gNBs = 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_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 - initialDLBWPk0_1 = 0; - initialDLBWPmappingType_1 = 0; - #this is SS=2,L=12 - initialDLBWPstartSymbolAndLength_1 = 53; + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 - 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 //5 (4 is for 43, 5 is for 57) - initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -90,7 +80,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -102,8 +92,9 @@ gNBs = prach_msg1_FDM = 0; prach_msg1_FrequencyStart = 74; zeroCorrelationZoneConfig = 13; - #preambleReceivedTargetPower = -118; - preambleReceivedTargetPower = -104; + preambleReceivedTargetPower = -118; + #preambleReceivedTargetPower = -104; + #preambleReceivedTargetPower = -108; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) preambleTransMax = 6; #powerRampingStep @@ -133,30 +124,30 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6; # used for UL slot initialULBWPmappingType_0 = 1 - # this is SS=0 L=11 - initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; - initialULBWPmappingType_1 = 1; - # this is SS=0 L=12 - initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12 - initialULBWPk2_2 = 7; + initialULBWPk2_1 = 6; # used for mixed slot + initialULBWPmappingType_1 = 1; + initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2 + + initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; - # this is SS=10 L=4 - initialULBWPstartSymbolAndLength_2 = 52; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 + msg3_DeltaPreamble = 1; - p0_NominalWithGrant =-90; + #p0_NominalWithGrant =-90; + p0_NominalWithGrant =-118; # pucch-ConfigCommon setup : # pucchGroupHopping # 0 = neither, 1= group hopping, 2=sequence hopping pucchGroupHopping = 0; hoppingId = 40; - p0_nominal = -90; + #p0_nominal = -90; + p0_nominal = -118; # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 2; @@ -189,7 +180,7 @@ gNBs = nrofUplinkSymbols = 4; //0; //4; #ssPBCH_BlockPower = 10; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -35; } ); @@ -229,9 +220,9 @@ gNBs = { GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.195/24"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.187/24"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.195/24"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.187/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 @@ -251,6 +242,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; + pusch_proc_threads = 8; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf new file mode 100644 index 0000000000..477240a3a0 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf @@ -0,0 +1,300 @@ +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 = 92; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is pointA + 23 PRBs@120kHz SCS (same as initial BWP) + absoluteFrequencySSB = 2071241; + dl_frequencyBand = 257; + # this is 27.900 GHz + dl_absoluteFrequencyPointA = 2070833; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 3; + dl_carrierBandwidth = 32; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=32 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 8525; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 3; + #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=3 + 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 //5 (4 is for 43, 5 is for 57) + initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 261; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 3; + ul_carrierBandwidth = 32; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 8525; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 3; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 52; +#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 = 7; +#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 = 3; +#oneHalf (0..15) 4,8,12,16,...60,64 + 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 +#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 = 3, + +# 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 = 4; + 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 = 3; + ssb_PositionsInBurst_Bitmap = 0x0001000100010001L; + +# 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 = 3; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 3; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 3; + 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.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 */ + 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.18.198/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + 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 + }; + } +); + +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]; + sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; + if_freq = 5124520000L; + clock_src = "external"; + time_src = "external"; + } +); + +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.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index f2e468c71b..8b1079350b 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 @@ -23,6 +23,9 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; servingCellConfigCommon = ( { @@ -33,10 +36,10 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL # this is pointA + 23 PRBs@120kHz SCS (same as initial BWP) - absoluteFrequencySSB = 2077907; + absoluteFrequencySSB = 2071241; dl_frequencyBand = 257; # this is 27.900 GHz - dl_absoluteFrequencyPointA = 2077499; + dl_absoluteFrequencyPointA = 2070833; #scs-SpecificCarrierList dl_offstToCarrier = 0; # subcarrierSpacing @@ -110,8 +113,8 @@ gNBs = #1,2,4,8,10,20,40,80 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 = 4; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 7; #ra_ContentionResolutionTimer @@ -140,7 +143,7 @@ gNBs = # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; - initialULBWPk2_2 = 14; + initialULBWPk2_2 = 4; initialULBWPmappingType_2 = 1; # this is SS=10 L=4 initialULBWPstartSymbolAndLength_2 = 52; @@ -157,7 +160,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 @@ -185,7 +188,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); @@ -216,6 +219,7 @@ gNBs = GNB_INTERFACE_NAME_FOR_S1U = "eth0"; GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; } ); @@ -247,9 +251,9 @@ RUs = ( max_rxgain = 75; eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; - if_freq = 5300000000L; - #time_source = "external"; - clock_source = "external"; + if_freq = 5124520000L; + clock_src = "external"; + time_src = "external"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf index 2737357851..3bfcc01703 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -176,7 +177,7 @@ gNBs = nrofUplinkSlots = 10; nrofUplinkSymbols = 0; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); 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 f810dd546c..e1bf1b9818 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 @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; @@ -112,8 +113,8 @@ gNBs = #1,2,4,8,10,20,40,80 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 = 4; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 7; #ra_ContentionResolutionTimer @@ -142,7 +143,7 @@ gNBs = # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; - initialULBWPk2_2 = 14; + initialULBWPk2_2 = 4; initialULBWPmappingType_2 = 1; # this is SS=10 L=4 initialULBWPstartSymbolAndLength_2 = 52; @@ -187,7 +188,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); @@ -249,6 +250,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; + pusch_proc_threads = 8; } ); 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 index 9e13d493a8..ceba30dacf 100644 --- 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 @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -185,7 +186,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); @@ -225,19 +226,20 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + pusch_proc_threads = 8; + } ); RUs = ( { - local_rf = "yes" + local_rf = "yes" nb_tx = 1; nb_rx = 1; att_tx = 0; @@ -246,8 +248,14 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 75; 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"; # if_freq = 3700000000L; 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 index 831f9c7978..115ed6f6f0 100644 --- 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 @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -185,7 +186,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); @@ -225,19 +226,20 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + pusch_proc_threads = 8; + } ); RUs = ( { - local_rf = "yes" + local_rf = "yes" nb_tx = 1; nb_rx = 1; att_tx = 0; @@ -246,8 +248,14 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; 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 = "type=x300"; clock_src = "external"; # if_freq = 3700000000L; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf index 1cd16d0831..b83999f25e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 31; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -46,7 +47,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -83,7 +84,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -176,7 +177,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf index dfae41f0a6..27ade965dc 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -46,7 +47,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=0,L=50 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -89,7 +90,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf index dcdfa003a2..9bb9132917 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf new file mode 100644 index 0000000000..ffced2055a --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf @@ -0,0 +1,339 @@ +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; + pusch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + + # downlinkConfigCommon + # frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641032; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6366; + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; + #prach_msg1_FDM + #0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; + #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; + #powerRampingStep + # 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; + #ra_ReponseWindow + #1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; + #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR + #1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; + #oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; + #ra_ContentionResolutionTimer + #(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; + #prach-RootSequenceIndex_PR + #1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + # restrictedSetConfig + # 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 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 = -25; + } + + ); + + # Dedicated Serving Cell Configuration + servingCellConfigDedicated = ( + { + # DL PTRS related parameters. + # 3GPP TS 38.331 PTRS-DownlinkConfig + + # frequencyDensity value range: 1-276 + dl_ptrsFreqDensity0_0 = 25; + dl_ptrsFreqDensity1_0 = 75; + + # timeDensity value range: 0-29 + dl_ptrsTimeDensity0_0 = 2; + dl_ptrsTimeDensity1_0 = 4; + dl_ptrsTimeDensity2_0 = 10; + + # epre_Ratio + # 0 = "00", 1 = "01" in TS 38.214, table 4.1-2 + dl_ptrsEpreRatio_0 = 0; + + # resourceElementOffset + # 0 = offset01 1 = offset02, 2 = offset02 + # 3GPP TS 38.331 PTRS-DownlinkConfig; TS 38.211 sec. 7.4.1.2.2 + dl_ptrsReOffset_0 = 0; + + # UL PTRS related parameters. + # 3GPP TS 38.331 PTRS-UplinkConfig + + # frequencyDensity value range: 1-276 + ul_ptrsFreqDensity0_0 = 25; + ul_ptrsFreqDensity1_0 = 75; + + # timeDensity value range: 0-29 + ul_ptrsTimeDensity0_0 = 2; + ul_ptrsTimeDensity1_0 = 4; + ul_ptrsTimeDensity2_0 = 10; + + # resourceElementOffset + # 0 = offset01 1 = offset02, 2 = offset02 + # TS 38.331 PTRS-UplinkConfig; TS 38.211 sec. 6.4.1.2.2.1 + ul_ptrsReOffset_0 = 0; + + # maxNrofPorts + # 0 = n1, 1 = n2 + ul_ptrsMaxPorts_0 = 0; + + # ptrs-Power + # 0 = p00, 1 = p01, 2 = p10, 3 = p11 + #ul_ptrsPower_0 = 0; + } + ); + + # ------- 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"; + pusch_proc_threads = 8; + } +); + +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 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 = "type=x300"; + clock_src = "external"; + } +); + +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.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf index 862f0e6303..b517bea8ee 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -176,7 +177,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); @@ -228,7 +229,7 @@ L1s = ( RUs = ( { - local_rf = "yes" + local_rf = "yes" nb_tx = 1 nb_rx = 1 att_tx = 0 @@ -237,7 +238,15 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - sdr_addrs = "type=b200"; + ## beamforming 1x2 matrix: 1 layer x 2 antennas + #bf_weights = [0x00007fff, 0x00007fff]; + ## 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 = "type=b200"; #clock_src = "external"; } ); 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 760689f653..7080aff8ea 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,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -46,7 +47,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=41,L=24 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -89,7 +90,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -158,7 +159,7 @@ gNBs = # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 2; - ssb_PositionsInBurst_Bitmap = 1; + ssb_PositionsInBurst_Bitmap = 0x1; # ssb_periodicityServingCell # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 @@ -186,7 +187,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); @@ -226,20 +227,20 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - pusch_proc_threads = 8; - } + pusch_proc_threads = 8; + } ); RUs = ( { - local_rf = "yes" + local_rf = "yes" nb_tx = 1 nb_rx = 1 att_tx = 0 @@ -248,15 +249,14 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 50; eNB_instances = [0]; - ##beamforming 1x2 matrix: 1 layer x 2 antennas - bf_weights = [0x00007fff, 0x0000]; - ##beamforming 1x4 matrix: 1 layer x 4 antennas + ## beamforming 1x2 matrix: 1 layer x 2 antennas + #bf_weights = [0x00007fff, 0x00007fff]; + ## beamforming 1x4 matrix: 1 layer x 4 antennas #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; ## beamforming 2x2 matrix: - # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + #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 d38fff4241..4039012fe1 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 @@ -23,7 +23,8 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; - + pusch_AntennaPorts = 1; + servingCellConfigCommon = ( { #spCellConfigCommon @@ -46,7 +47,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=0,L=50 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -89,7 +90,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -135,18 +136,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; @@ -187,7 +187,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; // -25 dBm/RE is the maximum measured power from USRP corresponding to att_tx = 0 dB } ); @@ -227,14 +227,15 @@ MACRLCs = ( num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + pusch_proc_threads = 8; + } ); RUs = ( @@ -248,8 +249,14 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; 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 = "type=x300"; clock_src = "external"; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index 0659641607..20e8aabf98 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -33,7 +34,7 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP) - absoluteFrequencySSB = 642364; + absoluteFrequencySSB = 642016;#642364; dl_frequencyBand = 78; # this is 3600 MHz dl_absoluteFrequencyPointA = 640000; @@ -130,16 +131,21 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6; #2; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - initialULBWPk2_1 = 2; + initialULBWPk2_1 = 6; #2; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -181,7 +187,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf index c907dcfe8d..fc8bda5d53 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -181,7 +182,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf new file mode 100644 index 0000000000..89dda14e20 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf @@ -0,0 +1,293 @@ +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; + pusch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 640288; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 24; + #initialDownlinkBWP + #genericParameters + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + 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=5 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 24; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6325; +# 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 = -25; + } + + ); + + + # ------- 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"; + pusch_proc_threads = 8; + } +); + +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 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 = "type=b200"; + #"addr=192.168.18.207"; + #"addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; + clock_src = "external"; + } +); + +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.24PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf new file mode 100644 index 0000000000..7954b3c201 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf @@ -0,0 +1,291 @@ +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; + pusch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 640288; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 24; + #initialDownlinkBWP + #genericParameters + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + 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=5 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 24; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6325; +# 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 = -25; + } + + ); + + + # ------- 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"; + pusch_proc_threads = 8; + } +); + +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 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"; + } +); + +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.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf new file mode 100644 index 0000000000..bd88ed88c7 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf @@ -0,0 +1,291 @@ +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; + pusch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 640288; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 24; + #initialDownlinkBWP + #genericParameters + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + 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=5 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 24; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6325; +# 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 = -25; + } + + ); + + + # ------- 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"; + pusch_proc_threads = 8; + } +); + +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 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 = "type=x300"; + clock_src = "external"; + } +); + +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.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf index 0a6268f8a8..694b78e08d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -130,16 +131,21 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6;#2; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - initialULBWPk2_1 = 2; + initialULBWPk2_1 = 6;#2; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -181,7 +187,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf new file mode 100644 index 0000000000..5cfd4dc768 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf @@ -0,0 +1,46 @@ +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 ="debug"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="debug"; + rrc_log_verbosity ="full"; +}; + + + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "lo"; + remote_n_address = "127.0.0.2"; // vnf addr + local_n_address = "127.0.0.1"; // pnf addr + local_n_portc = 50000; // pnf p5 port [!] + remote_n_portc = 50001; // vnf p5 port + local_n_portd = 50010; // pnf p7 port + remote_n_portd = 50011; // vnf p7 port + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + sdr_addrs = "type=x300"; // USRP type + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf new file mode 100644 index 0000000000..e541607559 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf @@ -0,0 +1,291 @@ +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; + pusch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641032; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6366; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 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; + } + + + ); + + + + 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.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; + local_s_if_name = "lo:"; + remote_s_address = "127.0.0.1"; // pnf addr [!] + local_s_address = "127.0.0.2"; // vnf addr + local_s_portc = 50001; // vnf p5 port + remote_s_portc = 50000; // pnf p5 port [!] + local_s_portd = 50011; // vnf p7 port [!] + remote_s_portd = 50010; // pnf p7 port [!] + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + } +) + + +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/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index 555af5835d..b2a765c447 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; @@ -48,7 +49,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -90,7 +91,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -249,7 +250,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - pusch_proc_threads = 8; + pusch_proc_threads = 8; } ); @@ -278,6 +279,18 @@ THREAD_STRUCT = ( } ); +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0", "nea2" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia0" ); +}; + log_config : { global_log_level ="info"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf new file mode 100644 index 0000000000..185edc5666 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf @@ -0,0 +1,307 @@ +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 = 01; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 31; //0; + pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 12 PRBs@30kHz SCS + absoluteFrequencySSB = 640288; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 24; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + 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 //5 (4 is for 43, 5 is for 57) + initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 24; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6325; +# 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 = 5; +#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; //15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 2; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 2; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=11 + 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; #0x80; + +# 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; //8; //7; + nrofDownlinkSymbols = 6; //0; //6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; //0; //4; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- 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.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 */ + 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.18.198/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + 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 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + } +); + +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 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]; + clock_src = "external"; + } +); + +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"; + //parallel_config = "PARALLEL_SINGLE_THREAD"; + #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/testing_gnb_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf index 6a3f008ec1..e8fcced386 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf @@ -23,6 +23,7 @@ gNBs = ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; servingCellConfigCommon = ( { @@ -46,7 +47,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=84,L=13 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -88,7 +89,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; 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 index 108cf06033..42b87d5672 100644 --- 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 @@ -51,7 +51,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=41,L=24 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; # 6366 12925 12956 28875 + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -99,7 +99,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; 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 index 4373f38e7b..96df4a971f 100644 --- 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 @@ -51,7 +51,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=41,L=24 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 6366; # 6366 12925 12956 28875 + initialDLBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -75,17 +75,12 @@ gNBs = initialDLBWPk0_2 = 0; initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 - initialDLBWPstartSymbolAndLength_2 = 95; + initialDLBWPstartSymbolAndLength_2 = 54; 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; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; #uplinkConfigCommon #frequencyInfoUL @@ -99,7 +94,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 6366; + initialULBWPlocationAndBandwidth = 6368; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 56c2cb23dd..368fd78f9e 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2986,6 +2986,7 @@ void RCconfig_RU(void) { 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; + RC.ru[j]->has_ctrl_prt =1; LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); } @@ -3039,6 +3040,7 @@ else { 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; + RC.ru[j]->has_ctrl_prt = 1; 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; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 1b4c651cf1..452b567fde 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -582,6 +582,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++) { + if(NFAPI_MODE != NFAPI_MODE_PNF) flexran_agent_start(i); }