diff --git a/.gitignore b/.gitignore index ff947966a2b9c7814a8ca64228810130cabe96f6..381c17661e952fc50a14afc6cbffe21b997bd124 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ -# vim swp *.swp -# log and exec file cmake_targets/log/ cmake_targets/*/build/ cmake_targets/ran_build/ @@ -12,9 +10,3 @@ targets/bin/ # vscode .vscode - -# Tags for vim/global -GPATH -GRTAGS -GTAGS -tags diff --git a/.vscode/launch.json b/.vscode/launch.json index 6757ed47f69371196c5fc2c82ece74f7cb6944fc..a138bccfd1f3d0d042112896ffffc7079a3d47fc 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,25 +4,156 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + + // { + // "type": "extensionHost", + // "request": "launch", + // "name": "Launch Extension", + // "runtimeExecutable": "${execPath}", + // "args": [ + // "--extensionDevelopmentPath=${workspaceFolder}" + // ], + // "outFiles": [ + // "${workspaceFolder}/out/**/*.js" + // ], + // "preLaunchTask": "npm" + // }, { - "name": "(gdb) Launch", + "name": "(gdb) Launch VNF", "type": "cppdbg", "request": "launch", - "program": "enter program name, for example ${workspaceFolder}/a.exe", - "args": [], - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], - "externalConsole": false, - "MIMode": "gdb", - "miDebuggerPath": "/path/to/gdb", - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } - ] - } - ] -} \ No newline at end of file + "program": "/home/glab/NR_nfapi/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem", + "args": ["-E", + "-O ", + "/home/glab/NR_nfapi/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf", + "--vnf"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + }, + { + "name": "(gdb) Launch PNF", + "type": "cppdbg", + "request": "launch", + "program": "/home/glab/NR_nfapi/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem", + "args": ["-E", + "-O ", + "/home/glab/NR_nfapi/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf", + "--pnf"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + { + "name": "(rfsim) PNF", + "type": "cppdbg", + "request": "launch", + "program": "/home/glab/NR_nfapi/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem", + "args": [ + "-O", + "/home/glab/NR_nfapi/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf", + "--pnf", + "--parallel-config", + "PARALLEL_SINGLE_THREAD", + "--rfsim", + "--rfsimulator.serveraddr", + "server"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + + + { + "name": "(gdb) Launch GNB", + "type": "cppdbg", + "request": "launch", + "program": " /home/glab/NR_nfapi/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem", + + + // "/home/glab/NR_nfapi/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem", + // "args": [, + // "-O ", + // "/home/glab/NR_nfapi/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf", + // "--parallel-config", + // "PARALLEL_SINGLE_THREAD", + // "--rfsim", + // "--phy-test"], + "args":["-O","/home/glab/NR_nfapi/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + { + "name": "(rfsim) Launch GNB", + "type": "cppdbg", + "request": "launch", + "program": " /home/glab/NR_nfapi/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem", + "args":["-O", + "/home/glab/NR_nfapi/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf", + "--rfsim", + "--rfsimulator.serveraddr", + "server", + "--phy-test"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] + } + + // PNF: oaiL1.nfapi.usrpx300.conf + // /home/glab/NR_nfapi/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem -E -O /home/glab/NR_nfapi/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf 1 + + // VNF: rcc.band78.tm1.106PRB.nfapi.conf + // /home/glab/NR_nfapi/openairinterface5g/cmake_targets/ran_build/build/nr-softmodem -E -O /home/glab/NR_nfapi/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf 2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7a8634f468aa5fe1a1b459638805e0e5b4d1c6f7..61e44bdd55c41b796f0a3fe162f6ac2923b1395d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,12 +2,13 @@ We want to make contributing to this project as easy and transparent as possible. +Please refer to the steps described on our website: [How to contribute to OAI](https://www.openairinterface.org/?page_id=112) + 1. Sign and return a Contributor License Agreement to OAI team. -2. We recommend that you provide us with a professional or student email address -2. Register on [Eurecom GitLab Server](https://gitlab.eurecom.fr/users/sign_in) -3. Provide the OAI team with the **username** of this account to (mailto:contact@openairinterface.org) ; we will give you the developer rights on this repository. +2. Create an account on [Eurecom GitLab Server](https://gitlab.eurecom.fr). +3. Provide the identifiant of this account to the OAI team (mailto:contact@openairinterface.org) so you have developer rights on this repository. 4. The policies are described in these wiki pages: [OAI Policies](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/oai-policies-home) - - PLEASE DO NOT FORK the OAI repository on your own Eurecom GitLab account. It just eats up space on our servers. + - PLEASE DO NOT FORK the OAI repository on your own Eurecom GitLab account. It just eats up space on our servers. - You can fork onto another hosting system. But we will NOT accept a merge request from a forked repository. * This decision was made for the license reasons. * The Continuous Integration will reject your merge request. diff --git a/NOTICE.md b/NOTICE.md index 39dd33795d71fa7b42d86a6ddc4fe9b7a6048c7d..96b5d4c552ed9752d8a8ba396c9c4df4293dc34b 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -21,7 +21,3 @@ The Regents of the University of California: BSD 3-Clause Licence. Niels Provos <provos@citi.umich.edu>: BSD 2-Clause Licence. -## Credits for source code openair3/GTPV1-U/nw-gtpv1u: ## - -Amit Chawre <http://www.amitchawre.net/contact.html>: BSD 2-Clause Licence. - diff --git a/ci-scripts/.gitignore b/ci-scripts/.gitignore index 34d19403a7c3f1169391296970ea44e99e4740a9..dc5e7c747645122e82e4e54a31492151d629680b 100644 --- a/ci-scripts/.gitignore +++ b/ci-scripts/.gitignore @@ -1,4 +1,3 @@ -r*.raw enb_*.log ue_*.log ping_*.* diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 9a6f3639548a4b185c2f835b7d193e4cc9ec8452..8dfa5c4ec4c93895262d81b6909fe54918d2cac1 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -30,14 +30,12 @@ def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { } } +def doRedHatBuild = false def doFlexranCtrlTest = false // Location of the executor node def nodeExecutor = params.nodeExecutor -// VM Lockable resources -def vmResource = params.vmLockableResource - pipeline { agent { label nodeExecutor @@ -68,8 +66,7 @@ pipeline { "Test-IF4p5-TDD-Band38-Multi-RRU", "Test-eNB-OAI-UE-FDD-Band7", "Test-Mono-FDD-Band13-X2-HO", - "Test-TDD-Band78-gNB-NR-UE", - "Test-OCP-FDD-Band7" + "Test-TDD-Band78-gNB-NR-UE" ]) ansiColor('xterm') } @@ -87,6 +84,21 @@ pipeline { echo "Platform is ${env.TESTPLATFORM_OWNER}" } + if (params.RedHatRemoteServer == null) { + allParametersPresent = false + } + if (params.RedHatRemoteCredentials == null) { + allParametersPresent = false + } + if (params.RedHatWorkingPath == null) { + allParametersPresent = false + } + if (allParametersPresent) { + echo "Performing Red Hat Build" + doRedHatBuild = true + } else { + doRedHatBuild = false + } if (params.FlexRanRtcGitLabRepository_Credentials != null) { doFlexranCtrlTest = true } @@ -162,81 +174,65 @@ pipeline { stage ("Start VM -- basic-sim") { steps { - lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } - } } } stage ("Start VM -- gnb-usrp") { steps { - lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } - } } } stage ("Start VM -- nr-ue-usrp") { steps { - lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } - } } } stage ("Start VM -- enb-usrp") { steps { - lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } - } } } stage ("Start VM -- phy-sim") { steps { - lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } - } } } stage ("Start VM -- enb-ethernet") { steps { - lock (vmResource) { - timeout (time: 7, unit: 'MINUTES') { + timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } - } } } stage ("Start VM -- ue-ethernet") { steps { - lock (vmResource) { - timeout (time: 7, unit: 'MINUTES') { + timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } - } } } stage ("Start VM -- cppcheck") { steps { - lock (vmResource) { - timeout (time: 7, unit: 'MINUTES') { + timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } - } } } @@ -282,7 +278,7 @@ pipeline { 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}" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } @@ -307,14 +303,33 @@ pipeline { } stage ("Build UE-ethernet") { steps { - // This is typically the last one to finish. - lock (vmResource) { gitlabCommitStatus(name: "Build UE-ethernet") { timeout (time: 20, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } - } + } + } + stage ("Build eNB-USRP on Red Hat") { + when { + expression {doRedHatBuild} + } + steps { + gitlabCommitStatus(name: "Build eNB-USRP-RHE") { + script { + try { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.RedHatRemoteCredentials}", usernameVariable: 'RH_Username', passwordVariable: 'RH_Password'] + ]) { + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/buildOnRH.sh --workspace $WORKSPACE --job-name ${JOB_NAME} --build-id ${BUILD_ID} --remote-host ${params.RedHatRemoteServer} --remote-path ${params.RedHatWorkingPath} --remote-user-name ${RH_Username} --remote-password ${RH_Password}" + } + } + } catch (Exception e) { + echo "Red Hat build failed but we could keep running pipeline if all ubuntu-based build passed" + } + } + } } } } @@ -376,7 +391,6 @@ pipeline { stages { stage ("Test physical simulators") { steps { - lock (vmResource) { script { timeout (time: 90, unit: 'MINUTES') { try { @@ -388,7 +402,6 @@ pipeline { } } } - } } } stage ("Build Flexran Controller") { @@ -396,7 +409,6 @@ pipeline { expression {doFlexranCtrlTest} } steps { - lock (vmResource) { script { timeout (time: 20, unit: 'MINUTES') { try { @@ -406,12 +418,10 @@ pipeline { } } } - } } } stage ("Test basic simulator") { steps { - lock (vmResource) { script { timeout (time: 30, unit: 'MINUTES') { try { @@ -423,12 +433,10 @@ pipeline { } } } - } } } stage ("Test L1 simulator") { steps { - lock (vmResource) { script { timeout (time: 30, unit: 'MINUTES') { try { @@ -440,14 +448,12 @@ pipeline { } } } - } } } stage ("Test RF simulator") { steps { - lock (vmResource) { script { - timeout (time: 40, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { try { gitlabCommitStatus(name: "Test RF-sim") { sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" @@ -457,12 +463,10 @@ pipeline { } } } - } } } stage ("Test L2 simulator") { steps { - lock (vmResource) { script { timeout (time: 30, unit: 'MINUTES') { try { @@ -474,14 +478,11 @@ pipeline { } } } - } } } stage ("Destroy all Virtual Machines") { steps { - lock (vmResource) { sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } } } } @@ -682,25 +683,6 @@ pipeline { } } } - stage ("Test OAI OCP-eNB - FDD - Band 7 - B210") { - steps { - script { - triggerSlaveJob ('OCPeNB-FDD-Band7-B210', 'Test-OCP-FDD-Band7') - } - } - post { - always { - script { - finalizeSlaveJob('OCPeNB-FDD-Band7-B210') - } - } - failure { - script { - currentBuild.result = 'FAILURE' - } - } - } - } } post { always { diff --git a/ci-scripts/args_parse.py b/ci-scripts/args_parse.py index 84b3a84514bf18afa15cdf04fdc38f4c0c1abbbc..cc2a473be417170d10173d7faa1027dfc6c53536 100644 --- a/ci-scripts/args_parse.py +++ b/ci-scripts/args_parse.py @@ -1,4 +1,3 @@ - # * 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. diff --git a/ci-scripts/checkAddedWarnings.sh b/ci-scripts/checkAddedWarnings.sh index bda8287a784862ddc7a050e2216385231f6d3e76..d366059a853cf39ea2deaa771dee93de2c5b2e8e 100755 --- a/ci-scripts/checkAddedWarnings.sh +++ b/ci-scripts/checkAddedWarnings.sh @@ -110,7 +110,7 @@ MODIFIED_FILES=`git log $TARGET_INIT_COMMIT..$MERGE_COMMMIT --oneline --name-sta NB_WARNINGS_FILES=0 # Retrieve list of warnings -LIST_WARNING_FILES=`egrep "error:|warning:" archives/*/*.Rel15.txt | egrep -v "jobserver unavailable|Clock skew detected.|flexran.proto" | sed -e "s#^.*/home/ubuntu/tmp/##" -e "s#^.*/tmp/CI-eNB/##" -e "s#common/utils/.*/itti#common/utils/itti#" | awk -F ":" '{print $1}' | sort | uniq` +LIST_WARNING_FILES=`egrep "error:|warning:" archives/*/*.Rel15.txt archives/*/basic_simulator_*txt | egrep -v "jobserver unavailable|Clock skew detected.|flexran.proto" | sed -e "s#^.*/home/ubuntu/tmp/##" -e "s#^.*/tmp/CI-eNB/##" -e "s#common/utils/.*/itti#common/utils/itti#" | awk -F ":" '{print $1}' | sort | uniq` echo "" echo "List of files that have been modified by the Merge Request AND" diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh index 3a2fcbb02cbba3692c65b0c597fde6edbc39d4b2..fb159d4da07db4662a48f297c5646c807ee05084 100755 --- a/ci-scripts/checkCodingFormattingRules.sh +++ b/ci-scripts/checkCodingFormattingRules.sh @@ -59,7 +59,7 @@ if [ $# -eq 0 ] then echo " ---- Checking the whole repository ----" echo "" - NB_FILES_TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt --recursive *.c *.h | grep -c Formatted || true` + NB_FILES_TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt --recursive *.c *.h | grep -c Formatted ` echo "Nb Files that do NOT follow OAI rules: $NB_FILES_TO_FORMAT" echo $NB_FILES_TO_FORMAT > ./oai_rules_result.txt @@ -67,17 +67,17 @@ then awk '/#[ \t]*ifndef/ { gsub("^.*ifndef *",""); if (names[$1]!="") print "files with same {define ", FILENAME, names[$1]; names[$1]=FILENAME } /#[ \t]*define/ { gsub("^.*define *",""); if(names[$1]!=FILENAME) print "error in declaration", FILENAME, $1, names[$1]; nextfile }' `find openair* common targets executables -name *.h |grep -v LFDS` > header-files-w-incorrect-define.txt # Testing if explicit GNU GPL license banner - egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "General Public License" . | egrep -v "openair3/NAS/COMMON/milenage.h" > files-w-gnu-gpl-license-banner.txt + egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "General Public License" . > files-w-gnu-gpl-license-banner.txt # Looking at exotic/suspect banner LIST_OF_FILES_W_BANNER=`egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "Copyright|copyleft" .` if [ -f ./files-w-suspect-banner.txt ]; then rm -f ./files-w-suspect-banner.txt; fi for FILE in $LIST_OF_FILES_W_BANNER do - IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true` - IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE || true` - IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE || true` - IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair3/NAS/COMMON/milenage.h" || true` + IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"` + IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE` + IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE` + IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h"` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] @@ -178,7 +178,7 @@ do EXT="${filename##*.}" if [ $EXT = "c" ] || [ $EXT = "h" ] || [ $EXT = "cpp" ] || [ $EXT = "hpp" ] then - TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt $FULLFILE | grep -c Formatted || true` + TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt $FULLFILE | grep -c Formatted ` NB_TO_FORMAT=$((NB_TO_FORMAT + TO_FORMAT)) if [ $TO_FORMAT -ne 0 ] then @@ -186,24 +186,20 @@ do echo $FULLFILE >> ./oai_rules_result_list.txt fi # Testing if explicit GNU GPL license banner - GNU_EXCEPTION=`echo $FULLFILE | egrep -c "openair3/NAS/COMMON/milenage.h" || true` - if [ $GNU_EXCEPTION -eq 0 ] - then - egrep -il "General Public License" $FULLFILE >> files-w-gnu-gpl-license-banner.txt - fi + egrep -i "General Public License" $FULLFILE >> files-w-gnu-gpl-license-banner.txt # Looking at exotic/suspect banner - IS_BANNER=`egrep -i -c "Copyright|copyleft" $FULLFILE || true` + IS_BANNER=`egrep -i -c "Copyright|copyleft" $FULLFILE` if [ $IS_BANNER -ne 0 ] then - IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true` - IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE || true` - IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE || true` - IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair3/NAS/COMMON/milenage.h" || true` + IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"` + IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE` + IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE` + IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h"` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] then - echo $FULLFILE >> ./files-w-suspect-banner.txt + echo $FILE >> ./files-w-suspect-banner.txt fi fi fi 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 aeba400cad73ace17cb920bb5a2802b74dfa37af..0fe2adc9054485d03c9344154a802b767e411d73 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -145,7 +145,6 @@ gNBs = initialULBWPmappingType_2 = 1; # this is SS=10 L=4 initialULBWPstartSymbolAndLength_2 = 52; - msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 8fbc3b93a0170cf9559403f2b414e598b33e36be..0358a056db9c5d02e1a265ab606d31d7fb6756ae 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -96,7 +96,6 @@ def AssignParams(params_dict): setattr(ldpc, key, value) - def GetParametersFromXML(action): if action == 'Build_eNB': RAN.Build_eNB_args=test.findtext('Build_eNB_args') diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 6425d55c8f98b870fbc4acb7b035a26885eb22bd..4f0844d8fb1a73a8d55c0a5f666f4c874cdbfa0f 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -880,7 +880,6 @@ class RANManagement(): nodeB_prefix = 'e' else: nodeB_prefix = 'g' - if self.air_interface[self.eNB_instance] == 'nr-softmodem': if ulschReceiveOK > 0: statMsg = nodeB_prefix + 'NB showed ' + str(ulschReceiveOK) + ' "ULSCH received ok" message(s)' diff --git a/ci-scripts/xml_files/fr1_multi_node_terminate.xml b/ci-scripts/xml_files/fr1_multi_node_terminate.xml new file mode 100644 index 0000000000000000000000000000000000000000..cbaaf8ba9975a8e464424e0ff258e64a5b3aabac --- /dev/null +++ b/ci-scripts/xml_files/fr1_multi_node_terminate.xml @@ -0,0 +1,50 @@ +<!-- + + 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 + +--> +<testCaseList> + <htmlTabRef>test-fr1-tm1</htmlTabRef> + <htmlTabName>Test-FR1-TM1</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <repeatCount>1</repeatCount> + <TestCaseRequestedList> + 070001 + 070000 + </TestCaseRequestedList> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="070000"> + <class>Terminate_eNB</class> + <desc>Terminate eNB</desc> + <eNB_instance>0</eNB_instance> + <eNB_serverId>0</eNB_serverId> + </testCase> + + <testCase id="070001"> + <class>Terminate_eNB</class> + <desc>Terminate gNB</desc> + <eNB_instance>1</eNB_instance> + <eNB_serverId>1</eNB_serverId> + </testCase> + +</testCaseList> + diff --git a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml new file mode 100644 index 0000000000000000000000000000000000000000..b2267efc77dcc514bcf07eda0c2223be3ed5b46a --- /dev/null +++ b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml @@ -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 + +--> +<testCaseList> + <htmlTabRef>test-airplane-mode</htmlTabRef> + <htmlTabName>AirplaneToggle</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <TestCaseRequestedList> + 010000 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="010000"> + <class>COTS_UE_Airplane</class> + <desc>Toggle COTS Airplane mode ON</desc> + <cots_ue_airplane_args>ON</cots_ue_airplane_args> + </testCase> + + +</testCaseList> diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 94d55d5fe5073825c0feabcfcdb2693afc2bc6cc..1828fba821cc7d17d07c9e9a4c56032e3041b1a0 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2131,7 +2131,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} @@ -2874,7 +2890,7 @@ 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 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 + 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) @@ -2985,7 +3001,7 @@ 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) @@ -3112,6 +3128,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) diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index 61a3984347212b7b3c753f855b4ff247df35a5ee..1f85e9fee4223f906698646a2f24f104aca46674 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -44,6 +44,7 @@ #include "../utils/LOG/log.h" #define CONFIG_SHAREDLIBFORMAT "libparams_%s.so" +extern uint8_t nfapi_mode; int load_config_sharedlib(configmodule_interface_t *cfgptr) { void *lib_handle; @@ -212,6 +213,17 @@ configmodule_interface_t *load_configmodule(int argc, if ( (strcmp(argv[i]+1, "h") == 0) || (strstr(argv[i]+1, "help_") != NULL ) ) { tmpflags = CONFIG_HELP; } + + if( strcmp(argv[i], "--vnf") == 0 ){ + printf("\nVNF ENABLED\n"); + nfapi_mode = 2; + } + + if( strcmp(argv[i], "--pnf") == 0 ){ + printf("\nPNF ENABLED\n"); + nfapi_mode = 1; + } + } /* look for the OAI_CONFIGMODULE environment variable */ diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index af4a57041f97eac1ac53a0ffd25afcd535b413b4..3f92662433060a27dce1f01bd63a9f1f129dce93 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -164,8 +164,54 @@ UE on machine 2: +As of February 2020, all 5G NR development is part of the develop branch (the branch develop-nr is no longer maintained). This also means that all new development will be merged into there once it passes all the CI. + +## NSA setup with COTS UE + +This setup requires an EPC, an OAI eNB and gNB, and a COTS Phone. A dedicated page describe the setup can be found [here](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home/gNB-COTS-UE-testing). + +### Launch gNB + +```bash sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf``` + +### Launch eNB + +```bash sudo ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf``` + + + +## phy-test setup with OAI UE + +The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC. In this case both gNB and eNB need to be run with the --phy-test flag. At the gNB this flag does the following + - it reads the RRC configuration from the configuration file + - it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw + - the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload + +At the UE the --phy-test flag will + - read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them. + + +### Launch gNB + +```bash sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test``` + +### Launch UE in another window +```bash sudo ./nr-uesoftmodem --phy-test [--rrc_config_path ../../../ci-scripts/rrc-files]``` + +Some other useful paramters of the UE are + - --ue-fo-compensation: enables the frequency offset compenstation at the UE. This is useful when running over the air and/or without an external clock/time source + - --usrp-args: this is the equivalend paramter of sdr_addrs field in the gNB config file and can be used to identify the USRP and set some basic paramters (like the clock source) + - --clock-source: sets the clock-source (internal or external). + - --time-source: sets the time-source (internal or external). + + +## noS1 setup with OAI UE + +Instead of randomly generated payload, in the phy-test mode we can also inject/receive user-plane traffic over a TUN interface. This is the so-called noS1 mode. + +This setup is described in the [rfsimulator page](../targets/ARCH/rfsimulator/README.md#5g-case). In theory this should also work with the real hardware target although this has yet to be tested. diff --git a/doc/testing_gnb_w_cots_ue_resources/gnb.conf b/doc/testing_gnb_w_cots_ue_resources/gnb.conf index c4a8d512b8e9b9200230996132ae6c8348db9e5d..3f697a08b028c336b81e35ba0cea1b9797a75011 100755 --- a/doc/testing_gnb_w_cots_ue_resources/gnb.conf +++ b/doc/testing_gnb_w_cots_ue_resources/gnb.conf @@ -212,8 +212,11 @@ gNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ +<<<<<<< HEAD +======= t_dc_prep = 1000; /* unit: millisecond */ t_dc_overall = 2000; /* unit: millisecond */ +>>>>>>> fork_develop_new target_enb_x2_ip_address = ( { ipv4 = "192.168.18.199"; ipv6 = "192:168:30::17"; diff --git a/executables/main-ocp.c b/executables/main-ocp.c index 6e5857d6d1666b6e6e9e0c043f4adc29571afb81..a1b239b3db45c3b2039e3bfb85baa4846e34e186 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 bd4a1a72aa868e14201c2588d284694df1a5ac34..93a2af10090e80ec3220f5705de53a80863a5b1d 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -135,16 +135,22 @@ 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 oai_slot_ind(uint16_t sfn, uint16_t slot); 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) { +struct timespec current; +clock_gettime(CLOCK_MONOTONIC, ¤t); +//LOG_I(PHY,"%sCurrent time %d.%d,frame_rx %d,slot_rx %d,frame_tx %d,slot_tx %d\n", __FUNCTION__, current.tv_sec,current.tv_nsec,frame_rx,slot_rx,frame_tx,slot_tx); + // if(nfapi_mode!=0) + // sf_ahead = (uint16_t) ceil((float)6/(0x01<<gNB->frame_parms.numerology_index)); sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - + start_meas(&softmodem_stats_rxtx_sf); // ******************************************************************* @@ -155,7 +161,9 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t //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|| @@ -396,15 +404,21 @@ static void *gNB_L1_thread( void *param ) { while (!oai_exit) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC,&t); + //printf("\nbefore time %d.%d\n",t.tv_sec,t.tv_nsec); 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 ); + clock_gettime(CLOCK_MONOTONIC,&t); 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; + + //printf("\nframe %d slot %d after wait time %d.%d\n",frame_rx,slot_rx,t.tv_sec,t.tv_nsec); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index feff0c29c2398ad8532da729488e741c9aeac61e..73a0c8909b687cfb9b17636ddfc92dd3d096fd40 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -97,7 +97,8 @@ static int DEFBFW[] = {0x00007fff}; extern volatile int oai_exit; - +extern struct timespec timespec_sub(struct timespec lhs, struct timespec rhs); +extern struct timespec timespec_add(struct timespec lhs, struct timespec rhs); extern void nr_phy_free_RU(RU_t *); extern void nr_phy_config_request(NR_PHY_Config_t *gNB); #include "executables/thread-common.h" @@ -114,6 +115,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; @@ -709,6 +711,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { + RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; nfapi_nr_config_request_scf_t *cfg = &ru->config; @@ -1540,9 +1543,35 @@ void *ru_thread( void *param ) { 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 + struct timespec slot_start; + clock_gettime(CLOCK_MONOTONIC, &slot_start); + + struct timespec slot_duration; + slot_duration.tv_sec = 0; + //slot_duration.tv_nsec = 0.5e6; + slot_duration.tv_nsec = 0.5e6; + + + while (!oai_exit) { // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // They are set on the first rx/tx in the underly FH routines. + slot_start = timespec_add(slot_start,slot_duration); + struct timespec curr_time; + clock_gettime(CLOCK_MONOTONIC, &curr_time); + + struct timespec sleep_time; + + if((slot_start.tv_sec > curr_time.tv_sec) || (slot_start.tv_sec == curr_time.tv_sec && slot_start.tv_nsec > curr_time.tv_nsec)){ + sleep_time = timespec_sub(slot_start,curr_time); + + usleep(sleep_time.tv_nsec * 1e-3); + } + else{//continue + } + + // clock_gettime(CLOCK_MONOTONIC, &curr_time); + //printf("sfn:%d, slot:%d, start time %d.%d slot start %d.%d \n",frame,slot,curr_time.tv_sec,curr_time.tv_nsec,slot_start.tv_sec,slot_start.tv_nsec); if (slot==(fp->slots_per_frame-1)) { slot=0; frame++; @@ -1561,7 +1590,7 @@ void *ru_thread( void *param ) { 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); + 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, diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index fb757a9f47cab8e3ff6965276a1392e0ee0124b3..b0f85592d340238477e0fa8cc0211c7f3314835a 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -820,6 +820,7 @@ void init_pdcp(void) { int main( int argc, char **argv ) { int ru_id, CC_id = 0; + start_background_system(); ///static configuration for NR at the moment @@ -892,7 +893,7 @@ if(!IS_SOFTMODEM_NOS1) AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n"); } else { printf("No ITTI, Initializing L1\n"); - RCconfig_L1(); + RCconfig_NR_L1(); } /* Start the agent. If it is turned off in the configuration, it won't start */ diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 5191551ea380cb27c7445d3730a6c41ab731af51..e5eafe9f330e37fab8244372a20ee7b72e3b93ad 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -151,6 +151,12 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, ue->prach_resources[gNB_id] = (NR_PRACH_RESOURCES_t *)malloc16_clear(sizeof(NR_PRACH_RESOURCES_t)); } + // Setting UE mode to NOT_SYNCHED by default + for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){ + ue->UE_mode[gNB_id] = NOT_SYNCHED; + ue->prach_resources[gNB_id] = (NR_PRACH_RESOURCES_t *)malloc16_clear(sizeof(NR_PRACH_RESOURCES_t)); + } + // initialize all signal buffers init_nr_ue_signal(ue, nb_connected_gNB, abstraction_flag); @@ -821,7 +827,7 @@ void *UE_thread(void *arg) { } void init_NR_UE(int nb_inst, char* rrc_config_path) { - int inst; + int inst; NR_UE_MAC_INST_t *mac_inst; NR_UE_RRC_INST_t* rrc_inst; diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 08834ed74022fccebe0651aa70bad61c65e8215e..12d60c09dd0df120855c0aed105f58eca108e8bf 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -91,7 +91,8 @@ extern const char *duplex_mode[]; pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex -uint16_t sf_ahead=6; //??? value ??? +uint16_t sf_ahead=4; //??? value ??? +// uint16_t slot_ahead = 6; pthread_cond_t sync_cond; pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. diff --git a/nfapi/CHANGES.md b/nfapi/CHANGES.md new file mode 100644 index 0000000000000000000000000000000000000000..b086cabf0441179e1bb15e303ff3abe8857828e9 --- /dev/null +++ b/nfapi/CHANGES.md @@ -0,0 +1,38 @@ +# Changelog + +### 14/06/20 +* we are not clear on how the parameters are extracted from the config file +* in ssc struct +* for some values it is okay and for others it is zero (in `config_request`) +* This causes Assertion Failures leading to termination on PNF side. + +### 15/06/20 +* The values to config request are assigned in: `config_common()` in `config.c` +* need to add lines for `cfg->nfapi_config` +* the config request unpacked on pnf side still has some zero values, which causes assertional failure in from_nrarfcn() + +### 16/06/20 +* Config request is recived and unpacked correctly +* Regarding config response + * we are confused about its' struct definition + * it says list of TLVs in its entirety + * and we need to dyanmically insert the invalid TLVs after checking in a categorical fashion + * Need to think of a data structure to enable this feature. + ```struct{ + list of uint8_t tlvs + list of uint16_t tlvs + list of uint32_t tlvs + }list of tlvs + ``` +* Need the `N_RB` value to be non-zero and obtained from the config file. (carrier config grid size) +`int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;` +* how is this `gNB_config` assigned its values? + +### 19/06/20 +* `ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);` sloc: 1428 in `nr-ru.c` +* the `ru->rfdevice` has all members zero or null. +* This issue was solved by adding `sdr_addrs` to config file of PNF. + +* `if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1` + * throws segmentation error + * `max_tdd_periodicity_list` is not assigned memory diff --git a/nfapi/nrNFAPI.md b/nfapi/nrNFAPI.md new file mode 100644 index 0000000000000000000000000000000000000000..607673305f25b5027b3ee27e3d6aaedb4f544bf2 --- /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 --vnf --noS1 --phy-test + +``` +### PNF command +``` +sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf --pnf --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/.vscode/launch.json b/nfapi/oai_integration/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..e006584180fb4816911da6fadf935955c82ae7eb --- /dev/null +++ b/nfapi/oai_integration/.vscode/launch.json @@ -0,0 +1,29 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "gcc - Build and debug active file", + "type": "cppdbg", + "request": "launch", + "program": "${fileDirname}/${fileBasenameNoExtension}", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "gcc build active file", + "miDebuggerPath": "/usr/bin/gdb" + } + ] +} \ No newline at end of file diff --git a/nfapi/oai_integration/.vscode/tasks.json b/nfapi/oai_integration/.vscode/tasks.json new file mode 100644 index 0000000000000000000000000000000000000000..456946dccef7670aa724ceaa443ae027a66d7145 --- /dev/null +++ b/nfapi/oai_integration/.vscode/tasks.json @@ -0,0 +1,23 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "shell", + "label": "C/C++: gcc build active file", + "command": "/usr/bin/gcc", + "args": [ + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "/usr/bin" + }, + "problemMatcher": [ + "$gcc" + ], + "group": "build" + } + ] +} \ No newline at end of file diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 3dfbc2811d2ff4518a6731db009f9d03dd0d0ac8..44df30448ec9dc3e9f08d23d90709c212e44f8f7 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] +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_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 = pnf->phys[0].local_port; // 32123; // 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,216 @@ 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->nfapi_config.rf_bands.tl.tag == NFAPI_NR_NFAPI_RF_BANDS_TAG) { + pnf->rfs[0].band = req->nfapi_config.rf_bands.rf_band[0]; + fp->nr_band = req->nfapi_config.rf_bands.rf_band[0]; + num_tlv++; + } + + if(req->nfapi_config.nrarfcn.tl.tag == NFAPI_NR_NFAPI_NRARFCN_TAG) { + // fp->dl_CarrierFreq = from_nrarfcn(78, req->ssb_config.scs_common.value , req->nfapi_config.nrarfcn.value);// TODO: get value nr_bandP + // fp->dl_CarrierFreq = req->carrier_config.dl_frequency.value; + // fp->ul_CarrierFreq = req->carrier_config.uplink_frequency.value; + + //fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_nr_uldl_offset(fp->nr_band) * 1e5); // TODO: why 1e5 ? + num_tlv++; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() nrarfcn:%u dl_carrierFreq:%u ul_CarrierFreq:%u band:%u N_RB_DL:%u\n", + __FUNCTION__, req->nfapi_config.nrarfcn.value, fp->dl_CarrierFreq, fp->ul_CarrierFreq, pnf->rfs[0].band, fp->N_RB_DL); + } + */ +#if SUBFRAME // TODO: add subframe struct to nr config request struct + if (req->subframe_config.duplex_mode.tl.tag == NFAPI_NR_SUBFRAME_CONFIG_DUPLEX_MODE_TAG) { + fp->frame_type = req->subframe_config.duplex_mode.value==0 ? TDD : FDD; + num_tlv++; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() frame_type:%d\n", __FUNCTION__, fp->frame_type); + +req->tdd_table. + if (req->subframe_config.dl_cyclic_prefix_type.tl.tag == NFAPI_NR_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG) { + fp->Ncp = req->subframe_config.dl_cyclic_prefix_type.value; + num_tlv++; + } + + if (req->subframe_config.ul_cyclic_prefix_type.tl.tag == NFAPI_NR_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG) { + fp->Ncp_UL = req->subframe_config.ul_cyclic_prefix_type.value; + num_tlv++; + } + + fp->num_MBSFN_config = 0; // DJP - hard code alert +#endif + + 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 LTE + if (req->rf_config.tx_antenna_ports.tl.tag == NFAPI_NR_RF_CONFIG_TX_ANTENNA_PORTS_TAG) { + fp->nb_antennas_tx = req->rf_config.tx_antenna_ports.value; + fp->nb_antenna_ports_eNB = 1; + num_tlv++; + } + + if (req->rf_config.rx_antenna_ports.tl.tag == NFAPI_NR_RF_CONFIG_RX_ANTENNA_PORTS_TAG) { + fp->nb_antennas_rx = req->rf_config.rx_antenna_ports.value; + num_tlv++; + } + + if (req->phich_config.phich_resource.tl.tag == NFAPI_NR_PHICH_CONFIG_PHICH_RESOURCE_TAG) { + fp->phich_config_common.phich_resource = req->phich_config.phich_resource.value; + num_tlv++; + } + + if (req->phich_config.phich_duration.tl.tag == NFAPI_NR_PHICH_CONFIG_PHICH_DURATION_TAG) { + fp->phich_config_common.phich_duration = req->phich_config.phich_duration.value; + num_tlv++; + } + + if (req->phich_config.phich_power_offset.tl.tag == NFAPI_NR_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG) { + LOG_E(PHY, "%s() NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG tag:%d not supported\n", __FUNCTION__, req->phich_config.phich_power_offset.tl.tag); + //fp->phich_config_common.phich_power_offset = req->phich_config. + num_tlv++; + } + + // UL RS Config + if (req->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag == NFAPI_NR_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG) { + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = req->uplink_reference_signal_config.cyclic_shift_1_for_drms.value; + num_tlv++; + } + + if (req->uplink_reference_signal_config.uplink_rs_hopping.tl.tag == NFAPI_NR_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG) { + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = req->uplink_reference_signal_config.uplink_rs_hopping.value; + num_tlv++; + } + + if (req->uplink_reference_signal_config.group_assignment.tl.tag == NFAPI_NR_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG) { + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = req->uplink_reference_signal_config.group_assignment.value; + num_tlv++; + } + + if (req->pusch_config.hopping_mode.tl.tag == NFAPI_NR_PUSCH_CONFIG_HOPPING_MODE_TAG) { + } // DJP - not being handled? + + if (req->pusch_config.hopping_offset.tl.tag == NFAPI_NR_PUSCH_CONFIG_HOPPING_OFFSET_TAG) { + } // DJP - not being handled? + + if (req->pusch_config.number_of_subbands.tl.tag == NFAPI_NR_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG) { + } // DJP - not being handled? + + if (req->prach_config.configuration_index.tl.tag == NFAPI_NR_PRACH_CONFIG_CONFIGURATION_INDEX_TAG) { + fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=req->prach_config.configuration_index.value; + num_tlv++; + } + + if (req->prach_config.root_sequence_index.tl.tag == NFAPI_NR_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG) { + fp->prach_config_common.rootSequenceIndex=req->prach_config.root_sequence_index.value; + num_tlv++; + } + + if (req->prach_config.zero_correlation_zone_configuration.tl.tag == NFAPI_NR_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG) { + fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=req->prach_config.zero_correlation_zone_configuration.value; + num_tlv++; + } + + if (req->prach_config.high_speed_flag.tl.tag == NFAPI_NR_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG) { + fp->prach_config_common.prach_ConfigInfo.highSpeedFlag=req->prach_config.high_speed_flag.value; + num_tlv++; + } + + if (req->prach_config.frequency_offset.tl.tag == NFAPI_NR_PRACH_CONFIG_FREQUENCY_OFFSET_TAG) { + fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset=req->prach_config.frequency_offset.value; + num_tlv++; + } +#endif + + 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); @@ -687,9 +1254,35 @@ nfapi_p7_message_header_t *pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, u return 0; } -void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) { - free(header); -} +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; i<req->numPdus; 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]; + handle_nfapi_nr_ul_dci_pdu(gNB, req->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) @@ -719,6 +1312,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; i<req->dl_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<NUMBER_OF_UE_MAX,"returned UE_id %d >= %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 +1494,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; i<req->Number_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 +1548,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 +1772,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 +1790,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 = 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 +1901,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 +2282,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,13 +2292,74 @@ void *pnf_start_thread(void *ptr) { return (void *)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) { +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__); 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.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; @@ -1422,7 +2408,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 +2427,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 2c8201737c8642a9b25bf9238c70465b1d4fdb7e..b3ab7cbdbc874ac08eeba71bb5975bb4a4ce7f44 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 6a33fba5c0d930f062c016efbbe4b2a2f47b6dee..98b621529bad0060e441f9774fba13ae5b243a44 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,7 +299,7 @@ int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { return 0; } -int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_response_t *resp) { +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; @@ -270,7 +318,42 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re 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); + 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; + } 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; @@ -396,6 +567,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; @@ -406,6 +578,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; @@ -917,6 +1112,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"); @@ -927,12 +1130,50 @@ void *vnf_p7_start_thread(void *ptr) { void set_thread_priority(int priority); +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->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_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; @@ -957,11 +1198,35 @@ 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_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; @@ -978,7 +1243,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; @@ -988,6 +1253,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 = 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); @@ -996,7 +1324,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 = 50010;//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 @@ -1006,7 +1334,7 @@ int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t req->header.phy_id = phy->id; printf("[VNF] Send NFAPI_CONFIG_REQUEST\n"); req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NFAPI_P7_VNF_PORT_TAG; - req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port; + req->nfapi_config.p7_vnf_port.value = 50011;//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_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; @@ -1042,6 +1370,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); @@ -1065,6 +1406,19 @@ 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, 32123, phy->id); + + // 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__); @@ -1109,6 +1463,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"); @@ -1118,7 +1479,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 = 32123; + 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)); @@ -1130,7 +1541,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 = 32123; vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t)); nfapi_vnf_config_t *config = nfapi_vnf_config_create(); config->malloc = malloc; @@ -1141,8 +1553,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; @@ -1185,13 +1599,15 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { int oai_nfapi_nr_dl_config_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; @@ -1201,6 +1617,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; @@ -1218,6 +1651,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!!!! @@ -1235,6 +1684,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 4ea26eda12d1a8d3feb1d9013830eff9c72b7b44..f4fd6a2bf9a221460cab3b2992bda0856a268fe0 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/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index 32a31a99f6a41206a6963ceeab31cb7f29786a1c..0eb77a9d262d0c1a64c7d26bd9e0f718bfb69c6b 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 650bda4f780138874f71ee40ee3b5098fb0d81e1..fbe7a0e170c7259aa72cb51ac697fc525a95a11e 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 <nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h> +#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 0000000000000000000000000000000000000000..6ee4ec840431454c5429456810abaa7a2f29fb59 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 c254e1a0282c0971038a83aeabc7c60f1f41a213..e84c7d983bbc44ea90f7bed99d16f610daeb9dd2 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, @@ -81,30 +64,35 @@ typedef enum { 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; +//same with nfapi_param_request_t + /*typedef struct { nfapi_nr_param_errors_e error_code; @@ -278,12 +266,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; @@ -465,9 +447,109 @@ 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 { + 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 { - uint8_t num_tlv; + 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; + nfapi_nr_param_errors_e 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; + nfapi_nr_param_errors_e error_code; // TODO: check if needed + + 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 +557,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; + nfapi_nr_config_errors_e 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 +591,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,7 +675,7 @@ 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 @@ -941,6 +1036,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 +1050,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 +1086,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 +1385,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 +1432,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 +1478,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 61c6875bc642c4866ac0cd2903b61424c5e9c270..ba800c36348ca16dc50d91b0cf02d90ff692bdf2 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 a8ac0f0a654716202e00ff051702505b3ee482bc..856cae31289e77038875f13fe202591e38efbc38 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c @@ -33,10 +33,18 @@ #include <nfapi_interface.h> #include <nfapi.h> +#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include <debug.h> // 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,32 @@ 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_tlv(NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, ppWritePackedMsg, end, &pack_pnf_rf_value) && + // pack_tlv(NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, ppWritePackedMsg, end, &pack_pnf_phy_rel10_value) && + // pack_tlv(NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, ppWritePackedMsg, end, &pack_pnf_phy_rel11_value) && + // pack_tlv(NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, ppWritePackedMsg, end, &pack_pnf_phy_rel12_value) && + // pack_tlv(NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, ppWritePackedMsg, end, &pack_pnf_phy_rel13_value) && + // pack_tlv(NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_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) @@ -242,15 +276,16 @@ static uint8_t pack_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, ui 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_tlv(NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, ppWritePackedMsg, end, &pack_pnf_rf_value) && - pack_tlv(NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, ppWritePackedMsg, end, &pack_pnf_phy_rel10_value) && - pack_tlv(NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, ppWritePackedMsg, end, &pack_pnf_phy_rel11_value) && - pack_tlv(NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, ppWritePackedMsg, end, &pack_pnf_phy_rel12_value) && - pack_tlv(NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, ppWritePackedMsg, end, &pack_pnf_phy_rel13_value) && - pack_tlv(NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_value) && - pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + // pack_tlv(NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, ppWritePackedMsg, end, &pack_pnf_rf_value) && + // pack_tlv(NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, ppWritePackedMsg, end, &pack_pnf_phy_rel10_value) && + // pack_tlv(NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, ppWritePackedMsg, end, &pack_pnf_phy_rel11_value) && + // pack_tlv(NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, ppWritePackedMsg, end, &pack_pnf_phy_rel12_value) && + // pack_tlv(NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, ppWritePackedMsg, end, &pack_pnf_phy_rel13_value) && + // pack_tlv(NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_value) && + 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 +305,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 +339,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 +369,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 +402,49 @@ 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_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 (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_int32_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_int32_tlv_t* value = (nfapi_int32_tlv_t*)tlv; + return pushs32(value->value, ppWritePackedMsg, end); +} + +static uint8_t unpack_int32_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + nfapi_int32_tlv_t* value = (nfapi_int32_tlv_t*)tlv; + return pulls32(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 +456,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; @@ -424,10 +550,144 @@ static uint8_t pack_embms_mbsfn_config_value(void* tlv, uint8_t **ppWritePackedM // 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) + +#if 0 +static uint8_t pack_array_tlv_uint8_t_iisc(uint8_t element_count, void *msg, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + + nfapi_uint8_tlv_t* list_of_tlvs = (nfapi_uint8_tlv_t*)msg; + + int ret = push8(element_count, ppWritePackedMsg, end); // pushing the element count + if(!ret) return ret; + + for(int i=0; i<element_count; i++) + { + ret = pack_uint8_tlv_value(x[i], ppWritePackedMsg, end); + if(!ret) return ret; + } + return ret; +} + +static uint8_t unpack_array_tlv_uint8_t_iisc(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ + uint8_t element_count = pull8(ppReadPackedMsg, &tlv, end); //pulling the element count + + nfapi_uint8_tlv_t* value; + + int ret = 0; + + for(int i=0; i<element_count; i++) + { + value = (nfapi_uint8_tlv_t*)(tlv); + ret = unpack_uint8_tlv_value(value->value, ppReadPackedMsg, end); + if(!ret) return ret; + } + + return ret; +} +#endif +// static uint8_t unpack_uint8_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +// { +// nfapi_uint8_tlv_t* value = (nfapi_uint8_tlv_t*)tlv; +// return pull8(ppReadPackedMsg, &value->value, end); +// } + + +static uint8_t pack_nr_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; + 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_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_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_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_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + */ + // vendor extension: + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config)); + +#if LTE +{ return( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) && push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) && pack_tlv(NFAPI_L1_STATUS_PHY_STATE_TAG, &pNfapiMsg->l1_status.phy_state, ppWritePackedMsg, end, &pack_uint16_tlv_value) && @@ -480,21 +740,21 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_ pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) && - pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_idx), ppWritePackedMsg, end, &pack_uint8_tlv_value) && - pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_id_r9), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_idx), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_id_r9), ppWritePackedMsg, end, &pack_uint16_tlv_value) && - pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_TAG, &(pNfapiMsg->embms_mbsfn_config), ppWritePackedMsg, end, &pack_embms_mbsfn_config_value) && + pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_TAG, &(pNfapiMsg->embms_mbsfn_config), ppWritePackedMsg, end, &pack_embms_mbsfn_config_value) && - pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && - pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) && - pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_config_flag), ppWritePackedMsg, end, &pack_uint8_tlv_value) && - pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_subframeconfig), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_config_flag), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_SUBFRAMECONFIG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_subframeconfig), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.bandwidth_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &(pNfapiMsg->srs_config.max_up_pts), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.srs_subframe_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && - pack_tlv(NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &(pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSset_tdd_config_nrMISSION_TAG, &(pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &(pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &(pNfapiMsg->uplink_reference_signal_config.group_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) && @@ -505,7 +765,7 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_ pack_tlv(NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &(pNfapiMsg->l23_config.data_report_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_L23_CONFIG_SFNSF_TAG, &(pNfapiMsg->l23_config.sfnsf), ppWritePackedMsg, end, &pack_uint16_tlv_value) && - pack_tlv(NFAPI_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_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && pack_tlv(NFAPI_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && @@ -524,7 +784,7 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_ pack_tlv(NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) && pack_tlv(NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && - pack_tlv(NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_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_NFAPI_EARFCN_TAG, &(pNfapiMsg->nfapi_config.earfcn), ppWritePackedMsg, end, &pack_uint16_tlv_value) && @@ -533,7 +793,8 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_ pack_tlv(NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_lte_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) && pack_tlv(NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &(pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported), ppWritePackedMsg, end, &pack_uint8_tlv_value) && pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); - +} +#endif } static uint8_t pack_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) @@ -668,31 +929,253 @@ 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->error_code, ppWritePackedMsg, end) && + 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) ); + +#if LTE +{ + push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) && + + // Do we check the phy state and then just fill those sepecified, however + // we do not know the duplex mode, so just attempt to pack all and assumme + // that the callee has set the right tlvs + + pack_tlv(NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG, &(pNfapiMsg->subframe_config.duplex_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG, &(pNfapiMsg->subframe_config.pcfich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_PB_TAG, &(pNfapiMsg->subframe_config.pb), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.dl_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG, &(pNfapiMsg->subframe_config.ul_cyclic_prefix_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.dl_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG, &(pNfapiMsg->rf_config.ul_channel_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG, &(pNfapiMsg->rf_config.reference_signal_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.tx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG, &(pNfapiMsg->rf_config.rx_antenna_ports), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG, &(pNfapiMsg->phich_config.phich_resource), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG, &(pNfapiMsg->phich_config.phich_duration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG, &(pNfapiMsg->phich_config.phich_power_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.primary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG, &(pNfapiMsg->sch_config.secondary_synchronization_signal_epre_eprers), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG, &(pNfapiMsg->sch_config.physical_cell_id), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->prach_config.configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->prach_config.zero_correlation_zone_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG, &(pNfapiMsg->prach_config.high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->prach_config.frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG, &(pNfapiMsg->pusch_config.hopping_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG, &(pNfapiMsg->pusch_config.hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG, &(pNfapiMsg->pusch_config.number_of_subbands), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG, &(pNfapiMsg->pucch_config.delta_pucch_shift), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG, &(pNfapiMsg->pucch_config.n_cqi_rb), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.bandwidth_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG, &(pNfapiMsg->srs_config.max_up_pts), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG, &(pNfapiMsg->srs_config.srs_subframe_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG, &(pNfapiMsg->srs_config.srs_acknack_srs_simultaneous_transmission), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG, &(pNfapiMsg->uplink_reference_signal_config.uplink_rs_hopping), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG, &(pNfapiMsg->uplink_reference_signal_config.group_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG, &(pNfapiMsg->uplink_reference_signal_config.cyclic_shift_1_for_drms), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG, &(pNfapiMsg->laa_config.ed_threshold_lbt_pdsch), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG, &(pNfapiMsg->laa_config.ed_threshold_lbt_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_PD_THRESHOLD_TAG, &(pNfapiMsg->laa_config.pd_threshold), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG, &(pNfapiMsg->laa_config.multi_carrier_type), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG, &(pNfapiMsg->laa_config.multi_carrier_tx), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG, &(pNfapiMsg->laa_config.multi_carrier_freeze), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG, &(pNfapiMsg->laa_config.tx_antenna_ports_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG, &(pNfapiMsg->laa_config.tx_power_drs), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG, &(pNfapiMsg->emtc_config.pbch_repetitions_enable_r13), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_catm_root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG, &(pNfapiMsg->emtc_config.prach_catm_zero_correlation_zone_configuration), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG, &(pNfapiMsg->emtc_config.prach_catm_high_speed_flag), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_0_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_1_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_2_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_configuration_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_frequency_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_starting_subframe_periodicity), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_hopping_enable), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG, &(pNfapiMsg->emtc_config.prach_ce_level_3_hopping_offset), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG, &(pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG, &(pNfapiMsg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG, &(pNfapiMsg->tdd_frame_structure_config.subframe_assignment), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG, &(pNfapiMsg->tdd_frame_structure_config.special_subframe_patterns), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + pack_tlv(NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG, &(pNfapiMsg->l23_config.data_report_mode), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_L23_CONFIG_SFNSF_TAG, &(pNfapiMsg->l23_config.sfnsf), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + + pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && + pack_tlv(NFAPI_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && + pack_tlv(NFAPI_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) && + pack_tlv(NFAPI_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) && + pack_tlv(NFAPI_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_PHY_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) && + + pack_tlv(NFAPI_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + pack_tlv(NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + pack_tlv(NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + pack_tlv(NFAPI_NFAPI_EARFCN_TAG, &(pNfapiMsg->nfapi_config.earfcn), ppWritePackedMsg, end, &pack_uint16_tlv_value) && + + + pack_tlv(NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_gsm_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) && + pack_tlv(NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_umts_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) && + pack_tlv(NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG, &(pNfapiMsg->nfapi_config.nmm_lte_frequency_bands), ppWritePackedMsg, end, &pack_nmm_frequency_bands_value) && + pack_tlv(NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG, &(pNfapiMsg->nfapi_config.nmm_uplink_rssi_supported), ppWritePackedMsg, end, &pack_uint8_tlv_value) && + + + pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) ); +} +#endif +} + +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_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +static uint8_t pack_nr_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; + 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_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) +static uint8_t pack_start_response(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; + nfapi_start_response_t *pNfapiMsg = (nfapi_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_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; return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); } @@ -733,6 +1216,110 @@ 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_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_STOP_RESPONSE: + result = pack_stop_response(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_MEASUREMENT_REQUEST: + result = pack_measurement_request(header, ppWritePackedMsg, end, config); + break; + + case NFAPI_MEASUREMENT_RESPONSE: + result = pack_measurement_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 +1439,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 +1542,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 +1758,28 @@ 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}, + /* + { NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, &unpack_pnf_rf_value}, + { NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, &unpack_pnf_phy_rel10_value}, + { NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, &unpack_pnf_phy_rel11_value}, + { 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_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) @@ -1118,18 +1790,21 @@ static uint8_t unpack_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end { { 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}, + /* { NFAPI_PNF_RF_TAG, &pNfapiMsg->pnf_rf, &unpack_pnf_rf_value}, { NFAPI_PNF_PHY_REL10_TAG, &pNfapiMsg->pnf_phy_rel10, &unpack_pnf_phy_rel10_value}, { NFAPI_PNF_PHY_REL11_TAG, &pNfapiMsg->pnf_phy_rel11, &unpack_pnf_phy_rel11_value}, { 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 +1823,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 +1849,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 +1876,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 +1899,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 +1912,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 +1960,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 +2069,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 +2288,72 @@ 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_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), &unpack_uint8_tlv_value}, + //{ NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), &unpack_uint16_tlv_value}, + //{ NFAPI_NR_NFAPI_NRARFCN_TAG, &(pNfapiMsg->nfapi_config.nrarfcn), &unpack_uint32_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_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), &unpack_rf_bands_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}, + //{ NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), &unpack_uint8_tlv_value}, + }; + 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_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) @@ -1468,9 +2368,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 +2415,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 +2493,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_START_RESPONSE: + if (unpackedBufLen >= sizeof(nfapi_nr_start_response_scf_t)) + retLen = sizeof(nfapi_nr_start_response_scf_t); + break; + + case NFAPI_STOP_REQUEST: + if (unpackedBufLen >= sizeof(nfapi_stop_request_t)) + retLen = sizeof(nfapi_stop_request_t); + break; + + case NFAPI_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 +2654,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 +2720,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_START_RESPONSE: + result = unpack_nr_start_response(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_STOP_REQUEST: + result = unpack_stop_request(&pReadPackedMessage, end, pMessageHeader, config); + break; + + case NFAPI_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 +2884,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 be9205d035ea075803e8e548925f1c8f3a9f1e8c..15870d5680cac96f85a9ad0faa9f455cdc657698 100755 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -36,6 +36,7 @@ #include <nfapi_interface.h> #include <nfapi.h> #include <debug.h> +#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); @@ -81,19 +82,19 @@ void* nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t* config) if(size == 0) return 0; - void* buffer_p = NULL; + void* buffer_p = NULL; if(config && config->allocate) { - buffer_p = (config->allocate)(size); - if(buffer_p != NULL){ - memset(buffer_p,0,size); - } - return buffer_p; + buffer_p = (config->allocate)(size); + if(buffer_p != NULL){ + memset(buffer_p,0,size); + } + return buffer_p; } else { - buffer_p = calloc(1, size); - return buffer_p; + buffer_p = calloc(1, size); + return buffer_p; } } @@ -226,6 +227,150 @@ static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t* value, uint8_t **ppW } + +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; + + // 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) && + pusharray16(value->dci_pdu.RNTI, MAX_DCI_CORESET, value->numDlDci, ppWritePackedMsg, end) && + pusharray16(value->dci_pdu.ScramblingId, MAX_DCI_CORESET, value->numDlDci, ppWritePackedMsg, end) && + + pusharray16(value->dci_pdu.ScramblingRNTI, MAX_DCI_CORESET, value->numDlDci, ppWritePackedMsg, end) && + pusharray8(value->dci_pdu.CceIndex, MAX_DCI_CORESET, value->numDlDci, ppWritePackedMsg, end) && + pusharray8(value->dci_pdu.AggregationLevel, MAX_DCI_CORESET, value->numDlDci, ppWritePackedMsg, end) && + pusharray8(value->dci_pdu.beta_PDCCH_1_0, MAX_DCI_CORESET, value->numDlDci, ppWritePackedMsg, end) && + + pusharray8(value->dci_pdu.powerControlOffsetSS, MAX_DCI_CORESET, value->numDlDci, ppWritePackedMsg, end) && + pusharray16(value->dci_pdu.PayloadSizeBits, MAX_DCI_CORESET, value->numDlDci, ppWritePackedMsg, end) && + pusharray8(value->dci_pdu.Payload[0], MAX_DCI_CORESET*DCI_PAYLOAD_BYTE_LEN, value->dci_pdu.PayloadSizeBits[0], 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; @@ -552,6 +697,55 @@ static uint8_t pack_dl_config_ndlsch_pdu_rel13_value(void* tlv, uint8_t **ppWrit 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; @@ -697,6 +891,41 @@ static uint8_t pack_dl_config_request_body_value(void* tlv, uint8_t **ppWritePac 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;i<pNfapiMsg->dl_tti_request_body.nGroup;i++) + { + for(int j=0;j<pNfapiMsg->dl_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;i<pNfapiMsg->dl_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; @@ -718,6 +947,9 @@ static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uin } } + + + 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; @@ -772,6 +1004,196 @@ static uint8_t pack_ul_config_request_ulsch_rel13_value(void *tlv, uint8_t **ppW 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) && @@ -1124,6 +1546,70 @@ static uint8_t pack_ul_config_request_nrach_pdu_rel13_value(void *tlv, uint8_t * } + + +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; i<value->n_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; @@ -1298,6 +1784,37 @@ static uint8_t pack_ul_config_request_body_value(void* tlv, uint8_t **ppWritePac 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; i<pNfapiMsg->n_pdus; i++) + { + if(!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end)) + return 0; + } + + for(int i=0; i<pNfapiMsg->n_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; @@ -1517,6 +2034,69 @@ static uint8_t pack_hi_dci0_request_body_value(void *tlv, uint8_t **ppWritePacke 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; + + 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) && + + push8(value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, ppWritePackedMsg, end) && + push16(value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end) && + pusharray16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.RNTI, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end) && + pusharray16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.ScramblingId, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end) && + + pusharray16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.ScramblingRNTI, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end) && + pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.CceIndex, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end) && + pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.AggregationLevel, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end) && + pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.beta_PDCCH_1_0, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end) && + + pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.powerControlOffsetSS, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end) && + pusharray16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.PayloadSizeBits, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end) && + pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.Payload[0], MAX_DCI_CORESET*DCI_PAYLOAD_BYTE_LEN, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.PayloadSizeBits[0], 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; i<pNfapiMsg->numPdus; 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; @@ -1526,6 +2106,55 @@ static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8 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; @@ -1551,7 +2180,7 @@ static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, // 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) + 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], @@ -1571,6 +2200,26 @@ static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, 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; i<pNfapiMsg->Number_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; @@ -1583,43 +2232,43 @@ static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e return x && y && z; } - -static uint8_t pack_release_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) -{ - nfapi_ue_release_request_body_t* value = (nfapi_ue_release_request_body_t*)tlv; - if(push16(value->number_of_TLVs, ppWritePackedMsg, end) == 0){ - return 0; - } - - uint8_t j; - uint16_t num = value->number_of_TLVs; - for(j = 0; j < num; ++j){ - if(push16(value->ue_release_request_TLVs_list[j].rnti, ppWritePackedMsg, end) == 0){ - return 0; - } - } - return 1; -} - -static uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg; - int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); - int y = pack_tlv(NFAPI_UE_RELEASE_BODY_TAG, &pNfapiMsg->ue_release_request_body, ppWritePackedMsg, end, &pack_release_request_body_value); - int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); - return x && y && z; -} - -static uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - - nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg; - - int x = push32(pNfapiMsg->error_code, ppWritePackedMsg, end); - int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); - return x && z; -} - + +static uint8_t pack_release_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +{ + nfapi_ue_release_request_body_t* value = (nfapi_ue_release_request_body_t*)tlv; + if(push16(value->number_of_TLVs, ppWritePackedMsg, end) == 0){ + return 0; + } + + uint8_t j; + uint16_t num = value->number_of_TLVs; + for(j = 0; j < num; ++j){ + if(push16(value->ue_release_request_TLVs_list[j].rnti, ppWritePackedMsg, end) == 0){ + return 0; + } + } + return 1; +} + +static uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg; + int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end); + int y = pack_tlv(NFAPI_UE_RELEASE_BODY_TAG, &pNfapiMsg->ue_release_request_body, ppWritePackedMsg, end, &pack_release_request_body_value); + int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + return x && y && z; +} + +static uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + + nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg; + + int x = push32(pNfapiMsg->error_code, ppWritePackedMsg, end); + int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config); + 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; @@ -2614,6 +3263,15 @@ static uint8_t pack_nrach_indication(void *msg, uint8_t **ppWritePackedMsg, uint 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; @@ -2623,6 +3281,16 @@ static uint8_t pack_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t 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; @@ -2636,7 +3304,7 @@ static uint8_t pack_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t 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) && @@ -2654,10 +3322,33 @@ static uint8_t pack_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t * 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_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) { nfapi_p7_message_header_t *pMessageHeader = pMessageBuf; uint8_t *pWritePackedMessage = pPackedBuf; @@ -2669,7 +3360,192 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu 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; + + 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_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) && @@ -2698,24 +3574,22 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu 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_TX_REQUEST: - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__); - result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config); + case NFAPI_UE_RELEASE_RESPONSE: + result =pack_ue_release_response(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; @@ -2834,10 +3708,152 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu 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; + // 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) && -// Unpack routines + 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) && + pullarray16(ppReadPackedMsg, value->dci_pdu.RNTI, MAX_DCI_CORESET, value->numDlDci, end) && + pullarray16(ppReadPackedMsg, value->dci_pdu.ScramblingId, MAX_DCI_CORESET, value->numDlDci, end) && + + pullarray16(ppReadPackedMsg, value->dci_pdu.ScramblingRNTI, MAX_DCI_CORESET, value->numDlDci, end) && + pullarray8(ppReadPackedMsg, value->dci_pdu.CceIndex, MAX_DCI_CORESET, value->numDlDci, end) && + pullarray8(ppReadPackedMsg, value->dci_pdu.AggregationLevel, MAX_DCI_CORESET,value->numDlDci, end) && + pullarray8(ppReadPackedMsg, value->dci_pdu.beta_PDCCH_1_0, MAX_DCI_CORESET, value->numDlDci, end) && + + pullarray8(ppReadPackedMsg, value->dci_pdu.powerControlOffsetSS, MAX_DCI_CORESET, value->numDlDci, end) && + pullarray16(ppReadPackedMsg, value->dci_pdu.PayloadSizeBits, MAX_DCI_CORESET, value->numDlDci, end) && + pullarray8(ppReadPackedMsg, value->dci_pdu.Payload[0], MAX_DCI_CORESET*DCI_PAYLOAD_BYTE_LEN,value->dci_pdu.PayloadSizeBits[0], 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; @@ -3279,37 +4295,88 @@ static uint8_t unpack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppRe 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) +static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) { - nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv; + nfapi_nr_dl_tti_request_pdu_t* value = (nfapi_nr_dl_tti_request_pdu_t*)msg; - 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(!(pull16(ppReadPackedMsg, &value->PDUSize, end) && + pull16(ppReadPackedMsg, &value->PDUType, 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) + // first match the pdu type, then call the respective function + switch(value->PDUType) { - 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) + case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate dl config pdu list (count:%d)\n", __FUNCTION__, value->number_pdu); - return 0; + if(!(unpack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppReadPackedMsg,end))) + return 0; } - } - else - { + 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; } @@ -3483,6 +4550,334 @@ static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPa 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;i<pNfapiMsg->dl_tti_request_body.nGroup;i++) + { + for(int j=0;j<pNfapiMsg->dl_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;i<pNfapiMsg->dl_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; @@ -3498,6 +4893,9 @@ static uint8_t unpack_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, 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) && @@ -3516,6 +4914,7 @@ static uint8_t unpack_ul_config_ulsch_pdu_rel8_value(void *tlv, uint8_t **ppRead 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; @@ -4415,6 +5814,64 @@ static uint8_t unpack_hi_dci0_request_body_value(void *tlv, uint8_t **ppReadPack 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; + + 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) && + pullarray16(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.RNTI, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end) && + pullarray16(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.ScramblingId, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end) && + + pullarray16(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.ScramblingRNTI, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end) && + pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.CceIndex, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end) && + pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.AggregationLevel, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end) && + pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.beta_PDCCH_1_0, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end) && + + pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.powerControlOffsetSS, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end) && + pullarray16(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.PayloadSizeBits, MAX_DCI_CORESET, value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end) && + pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.Payload[0], MAX_DCI_CORESET*DCI_PAYLOAD_BYTE_LEN, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu.PayloadSizeBits[0], 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) { @@ -4429,6 +5886,72 @@ static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, v 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) { @@ -4479,43 +6002,43 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void * 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 (pdu) { + uint16_t length = 0; + uint16_t index = 0; - if(!(pull16(ppReadPackedMsg, &length, end) && + if(!(pull16(ppReadPackedMsg, &length, end) && pull16(ppReadPackedMsg, &index, end))) - return 0; + return 0; - pdu->pdu_length = length; - pdu->pdu_index = index; + pdu->pdu_length = length; + pdu->pdu_index = index; // 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); + 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)) + 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; - if (pdu->segments[0].segment_length == 3) - { + 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] ); - } - } - else - { + } + } + 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); - } - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n"); - } + } + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n"); + } } } break; @@ -4529,55 +6052,55 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void * return 1; } - -static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config) -{ - uint8_t proceed = 1; - nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_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_UE_RELEASE_BODY_TAG: - { - pNfapiMsg->ue_release_request_body.tl = generic_tl; - if( pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.number_of_TLVs, end) == 0) - return 0; - - if(pNfapiMsg->ue_release_request_body.number_of_TLVs > NFAPI_RELEASE_MAX_RNTI) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of relese rnti's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->ue_release_request_body.number_of_TLVs, NFAPI_RELEASE_MAX_RNTI); - return 0; - } else { - uint8_t j; - uint16_t num = pNfapiMsg->ue_release_request_body.number_of_TLVs; - for(j = 0; j < num; ++j){ - if(pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.ue_release_request_TLVs_list[j].rnti, end) == 0){ - return 0; - } - } - } - } - break; - default: - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_ue_release_request FIXME : Invalid 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) +{ + uint8_t proceed = 1; + nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_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_UE_RELEASE_BODY_TAG: + { + pNfapiMsg->ue_release_request_body.tl = generic_tl; + if( pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.number_of_TLVs, end) == 0) + return 0; + + if(pNfapiMsg->ue_release_request_body.number_of_TLVs > NFAPI_RELEASE_MAX_RNTI) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of relese rnti's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->ue_release_request_body.number_of_TLVs, NFAPI_RELEASE_MAX_RNTI); + return 0; + } else { + uint8_t j; + uint16_t num = pNfapiMsg->ue_release_request_body.number_of_TLVs; + for(j = 0; j < num; ++j){ + if(pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.ue_release_request_TLVs_list[j].rnti, end) == 0){ + return 0; + } + } + } + } + break; + default: + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_ue_release_request FIXME : Invalid type %d \n", generic_tl.tag ); + } + break; + }; + } + + 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; @@ -5825,18 +7348,18 @@ static uint8_t unpack_nrach_indication_rel13_value(void *tlv, uint8_t **ppReadPa 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; - if(pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) == 0){ - return 0; - } - else{ - NFAPI_TRACE(NFAPI_TRACE_INFO, "ue_release_response:error_code = %d\n", pNfapiMsg->error_code); - } - return 1; -} - +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; + if(pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) == 0){ + return 0; + } + else{ + NFAPI_TRACE(NFAPI_TRACE_INFO, "ue_release_response:error_code = %d\n", pNfapiMsg->error_code); + } + 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; @@ -5894,6 +7417,19 @@ static uint8_t unpack_nrach_indication(uint8_t **ppReadPackedMsg, uint8_t *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; @@ -5907,6 +7443,22 @@ static uint8_t unpack_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void 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; @@ -5928,7 +7480,7 @@ static uint8_t unpack_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void 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) && @@ -5947,7 +7499,35 @@ static uint8_t unpack_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void } -// unpack length check +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) { @@ -6049,17 +7629,17 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen 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; - + + 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; @@ -6068,6 +7648,126 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen 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 @@ -6119,7 +7819,15 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn 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); @@ -6151,7 +7859,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn // 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); @@ -6165,28 +7873,26 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn else return -1; break; - - case NFAPI_HI_DCI0_REQUEST: + 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_TX_REQUEST: - if (check_unpack_length(NFAPI_TX_REQUEST, unpackedBufLen)) - result = unpack_tx_request(&pReadPackedMessage, end, pMessageHeader, config); + case NFAPI_UE_RELEASE_REQUEST: + if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen)) + result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config); else return -1; break; - - case NFAPI_UE_RELEASE_REQUEST: - if (check_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_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen)) result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config); @@ -6284,14 +7990,14 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn else return -1; break; - - case NFAPI_UE_RELEASE_RESPONSE: - if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen)) - result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config); - else - return -1; - break; - + + case NFAPI_UE_RELEASE_RESPONSE: + if (check_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 && @@ -6319,3 +8025,228 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn 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 ab38c66e090f1f2ed6d010988465155e25fa8ca8..8c4e5cf9ab083c03c034f7dad57d8703328bd6d1 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 3f08d85e6b678aff5c15c733b3361c65ab81961c..1e2e2fa21d25733a26ee24ffe4c1bd0381330db8 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 d169177d6b182eeae05d4290c1fa88e3248cd1c7..8b8edd7fd6ee07c13549eb69077f945163b2bd8b 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 <openair2/PHY_INTERFACE/IF_Module.h> +#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include <sys/types.h> +#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 @@ -355,6 +366,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 +383,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 +393,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 +402,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 +418,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 +427,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 +435,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 +567,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 +635,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 +646,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 +656,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 +664,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 +672,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 +684,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 +748,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 +758,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 eec9ff80c38a98f0425c4a3d8d30b433f6a974b7..20c6c12a7462c961f46fb34815f9f16e8b11852f 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf.c +++ b/nfapi/open-nFAPI/pnf/src/pnf.c @@ -26,9 +26,29 @@ #include <string.h> #include <unistd.h> #include <errno.h> - +#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,9 +502,8 @@ void pnf_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } } -void pnf_handle_config_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) { @@ -340,55 +511,56 @@ void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } else { - nfapi_config_request_t req; - - NFAPI_TRACE(NFAPI_TRACE_INFO, "CONFIG.request received\n"); - + 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_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + 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(phy->state == NFAPI_PNF_PHY_IDLE) { - if(config->config_req) + if(config->nr_param_req) { - (config->config_req)(config, phy, &req); + (config->nr_param_req)(config, phy, &req); } } else { - nfapi_config_response_t resp; + nfapi_nr_param_response_scf_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_CONFIG_RESPONSE; + 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_pnf_config_resp(config, &resp); + nfapi_nr_pnf_param_resp(config, &resp); } } else { - nfapi_config_response_t resp; + nfapi_nr_param_response_scf_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_CONFIG_RESPONSE; + 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_pnf_config_resp(config, &resp); + nfapi_nr_pnf_param_resp(config, &resp); } + } else { - nfapi_config_response_t resp; + nfapi_nr_param_response_scf_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_CONFIG_RESPONSE; + 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_pnf_config_resp(config, &resp); + nfapi_nr_pnf_param_resp(config, &resp); } } else @@ -398,11 +570,13 @@ void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); + } } -void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { + // ensure it's valid if (pRecvMsg == NULL || pnf == NULL) { @@ -410,12 +584,12 @@ void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } else { - nfapi_start_request_t req; + nfapi_config_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "CONFIG.request received\n"); 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_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -426,54 +600,55 @@ void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { if(phy->state != NFAPI_PNF_PHY_RUNNING) { - if(config->start_req) + if(config->config_req) { - (config->start_req)(config, phy, &req); + (config->config_req)(config, phy, &req); } } else { - nfapi_start_response_t resp; + nfapi_config_response_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_START_RESPONSE; + resp.header.message_id = NFAPI_CONFIG_RESPONSE; resp.header.phy_id = req.header.phy_id; resp.error_code = NFAPI_MSG_INVALID_STATE; - nfapi_pnf_start_resp(config, &resp); + nfapi_pnf_config_resp(config, &resp); } } else { - nfapi_start_response_t resp; + nfapi_config_response_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_START_RESPONSE; + resp.header.message_id = NFAPI_CONFIG_RESPONSE; resp.header.phy_id = req.header.phy_id; resp.error_code = NFAPI_MSG_INVALID_CONFIG; - nfapi_pnf_start_resp(config, &resp); + nfapi_pnf_config_resp(config, &resp); } } else { - nfapi_start_response_t resp; + nfapi_config_response_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_START_RESPONSE; + resp.header.message_id = NFAPI_CONFIG_RESPONSE; resp.header.phy_id = req.header.phy_id; resp.error_code = NFAPI_MSG_INVALID_STATE; - nfapi_pnf_start_resp(config, &resp); + nfapi_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_stop_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) { @@ -481,69 +656,75 @@ void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } else { - nfapi_stop_request_t req; + nfapi_nr_config_request_scf_t req; - NFAPI_TRACE(NFAPI_TRACE_INFO, "STOP.request received\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "CONFIG.request received\n"); nfapi_pnf_config_t* config = &(pnf->_public); // unpack the message - if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) + 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->stop_req) + if(config->nr_config_req) { - (config->stop_req)(config, phy, &req); + (config->nr_config_req)(config, phy, &req); + + } } else { - nfapi_stop_response_t resp; + nfapi_nr_config_response_scf_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_STOP_RESPONSE; + resp.header.message_id = NFAPI_CONFIG_RESPONSE; resp.header.phy_id = req.header.phy_id; resp.error_code = NFAPI_MSG_INVALID_STATE; - nfapi_pnf_stop_resp(config, &resp); + nfapi_nr_pnf_config_resp(config, &resp); } } else { - nfapi_stop_response_t resp; + nfapi_nr_config_response_scf_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_STOP_RESPONSE; + resp.header.message_id = NFAPI_CONFIG_RESPONSE; resp.header.phy_id = req.header.phy_id; resp.error_code = NFAPI_MSG_INVALID_CONFIG; - nfapi_pnf_stop_resp(config, &resp); + nfapi_nr_pnf_config_resp(config, &resp); } } else { - nfapi_stop_response_t resp; + nfapi_nr_config_response_scf_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_STOP_RESPONSE; + resp.header.message_id = NFAPI_CONFIG_RESPONSE; resp.header.phy_id = req.header.phy_id; resp.error_code = NFAPI_MSG_INVALID_STATE; - nfapi_pnf_stop_resp(config, &resp); + 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_measurement_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) +void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { // ensure it's valid if (pRecvMsg == NULL || pnf == NULL) @@ -552,12 +733,12 @@ void pnf_handle_measurement_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } else { - nfapi_measurement_request_t req; - - NFAPI_TRACE(NFAPI_TRACE_INFO, "MEASUREMENT.request received\n"); + nfapi_start_request_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_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -568,46 +749,330 @@ void pnf_handle_measurement_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { if(phy->state != NFAPI_PNF_PHY_RUNNING) { - if(config->measurement_req) + if(config->start_req) { - (config->measurement_req)(config, phy, &req); + (config->start_req)(config, phy, &req); } } else { - nfapi_measurement_response_t resp; + nfapi_start_response_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.message_id = NFAPI_START_RESPONSE; resp.header.phy_id = req.header.phy_id; resp.error_code = NFAPI_MSG_INVALID_STATE; - nfapi_pnf_measurement_resp(config, &resp); + nfapi_pnf_start_resp(config, &resp); } } else { - nfapi_measurement_response_t resp; + nfapi_start_response_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.message_id = NFAPI_START_RESPONSE; resp.header.phy_id = req.header.phy_id; resp.error_code = NFAPI_MSG_INVALID_CONFIG; - nfapi_pnf_measurement_resp(config, &resp); + nfapi_pnf_start_resp(config, &resp); } } else { - nfapi_measurement_response_t resp; + nfapi_start_response_t resp; memset(&resp, 0, sizeof(resp)); - resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.message_id = NFAPI_START_RESPONSE; resp.header.phy_id = req.header.phy_id; resp.error_code = NFAPI_MSG_INVALID_STATE; - nfapi_pnf_measurement_resp(config, &resp); + nfapi_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_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_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_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_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 + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_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_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->stop_req) + { + (config->stop_req)(config, phy, &req); + } + } + else + { + nfapi_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_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_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_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_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->stop_req) + { + (config->stop_req)(config, phy, &req); + } + } + else + { + nfapi_stop_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_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_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_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 + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_measurement_request_t req; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "MEASUREMENT.request received\n"); + + nfapi_pnf_config_t* config = &(pnf->_public); + + // unpack the message + if (nfapi_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->measurement_req) + { + (config->measurement_req)(config, phy, &req); + } + } + else + { + nfapi_measurement_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_measurement_resp(config, &resp); + } + } + else + { + nfapi_measurement_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_CONFIG; + nfapi_pnf_measurement_resp(config, &resp); + } + } + else + { + nfapi_measurement_response_t resp; + memset(&resp, 0, sizeof(resp)); + resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; + resp.header.phy_id = req.header.phy_id; + resp.error_code = NFAPI_MSG_INVALID_STATE; + nfapi_pnf_measurement_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); } @@ -1030,49 +1495,143 @@ void pnf_handle_nmm_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) } -void pnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_t* pnf, uint16_t message_id) -{ - if (pRecvMsg == NULL || pnf == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); - } - else - { - nfapi_pnf_config_t* config = &(pnf->_public); - - if(config->allocate_p4_p5_vendor_ext) - { - uint16_t msg_size; - nfapi_p4_p5_message_header_t* msg = config->allocate_p4_p5_vendor_ext(message_id, &msg_size); - - if(msg == 0) - { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n"); - return; - } - - - int unpack_result = nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, msg, msg_size, &config->codec_config); - - if(unpack_result == 0) - { - if(config->vendor_ext) - config->vendor_ext(config, msg); - } - else +void pnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_t* pnf, uint16_t message_id) +{ + if (pRecvMsg == NULL || pnf == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); + } + else + { + nfapi_pnf_config_t* config = &(pnf->_public); + + if(config->allocate_p4_p5_vendor_ext) + { + uint16_t msg_size; + nfapi_p4_p5_message_header_t* msg = config->allocate_p4_p5_vendor_ext(message_id, &msg_size); + + if(msg == 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n"); + return; + } + + + int unpack_result = nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, msg, msg_size, &config->codec_config); + + if(unpack_result == 0) + { + if(config->vendor_ext) + config->vendor_ext(config, msg); + } + else + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + } + + if(config->deallocate_p4_p5_vendor_ext) + config->deallocate_p4_p5_vendor_ext(msg); + + } + } +} + +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: { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); + 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); + } } - - if(config->deallocate_p4_p5_vendor_ext) - config->deallocate_p4_p5_vendor_ext(msg); - - } + break; } } - - void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { nfapi_p4_p5_message_header_t messageHeader; @@ -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; i<len; i++){ + printf("%d", msg[i]); + } + printf("\n"); + if (sctp_sendmsg(pnf->p5_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; i<message_size; i++){ + printf("%d", read_buffer[i]); + } + printf("\n"); + if (flags & MSG_NOTIFICATION) { NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); @@ -1533,6 +2123,135 @@ int pnf_read_dispatch_message(pnf_t* pnf) return socket_connected; +} + +int pnf_nr_read_dispatch_message(pnf_t* pnf) +{ + 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*/ 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; i<message_size; i++){ + printf("%d", read_buffer[i]); + } + printf("\n"); + + 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) + { + 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 dda0d0fdc60ce5f632b12962ac502877c72e9aff..8c9722c13e6df95df9115165ea70412ec0c19835 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_interface.c @@ -19,6 +19,8 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#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 5ba912e059f73b5c15b3d8e5a4e490ddc2000cd6..9fc287d3e6b42564e99fe84d90f234899d007b1c 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; // changed from 1e6 - gokul + } + + 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,14 +543,18 @@ 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 struct sockaddr_in remote_addr; 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); + remote_addr.sin_port = htons(32123);//htons(pnf_p7->_public.remote_p7_port); //hardcoding for now + //remote_addr.sin_addr.s_addr = inet_addr(pnf_p7->_public.remote_p7_addr); + //remote_addr.sin_port = 0; // hardcoded by Gokul + 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 +564,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 +669,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 +791,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,7 +914,8 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf) } } -int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, 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 @@ -610,58 +926,368 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf) // 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; } -#if 1 - // save the curren time and sfn_sf - pnf_p7->sf_start_time_hr = pnf_get_current_time_hr(); - pnf_p7->sfn_sf = sfn_sf; + // 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 sfn_sf_tx = sfnsf_add_sf(sfn_sf, sf_ahead); - uint32_t tx_sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf_tx); + // 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.subframe_buffer_size != 0) + 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->sfn_sf_shift != 0) + if(pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync { - int32_t sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf); - - int32_t shifted_sfn_sf = sfn_sf_dec += pnf_p7->sfn_sf_shift; + uint16_t shifted_slot = slot + pnf_p7->slot_shift; // adjust for wrap-around - if(shifted_sfn_sf < 0) - shifted_sfn_sf += NFAPI_MAX_SFNSFDEC; - else if(shifted_sfn_sf > NFAPI_MAX_SFNSFDEC) - shifted_sfn_sf -= NFAPI_MAX_SFNSFDEC; + 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/sf (%d -> %d)\n", pnf_p7->sfn_sf_shift, NFAPI_SFNSF2DEC(sfn_sf), shifted_sfn_sf); - sfn_sf = shifted_sfn_sf; + // 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??? - // + // + // DJP - why does the shift not apply to pnf_p7->sfn_sf??? + // - pnf_p7->sfn_sf_shift = 0; + pnf_p7->slot_shift = 0; } - uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf); - uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + uint32_t slot_dec = NFAPI_SFNSLOT2DEC(sfn, slot); + uint8_t buffer_index = slot_dec % pnf_p7->_public.slot_buffer_size; - nfapi_pnf_p7_subframe_buffer_t* subframe_buffer = &(pnf_p7->subframe_buffer[buffer_index]); + 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_sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; - nfapi_pnf_p7_subframe_buffer_t* tx_subframe_buffer = &(pnf_p7->subframe_buffer[tx_buffer_index]); + 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]); - //printf("sfn_sf_dec:%d tx_sfn_sf_dec:%d\n", sfn_sf_dec, tx_sfn_sf_dec); - if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d subframe_buffer->sfn_sf:%d tx_subframe_buffer->sfn_sf:%d sfn_sf:%d subframe_buffer[buffer_index:%u dl_config_req:%p tx_req:%p] " + //printf("sfn_sf_dec:%d tx_sfn_sf_dec:%d\n", sfn_sf_dec, tx_sfn_sf_dec); + 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); + } + //deallocate_nfapi_tx_request(slot_buffer->tx_req, pnf_p7); + } + 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; // TODO: change tx_req to nfapi_nr_tx_data_request_t + 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) + { + + //printf("\nIn pnf_phy_dl_tti_req VNF: sfn %d slot %d, PNF: sfn %d slot %d slot buffer sfn %d %d \n",tx_slot_buffer->dl_tti_req->SFN,tx_slot_buffer->dl_tti_req->Slot,pnf_p7->sfn,pnf_p7->slot); + + (pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), tx_slot_buffer->dl_tti_req); + } + //deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7); + } + + + 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; // TODO: Change dl_config_req to nfapi_nr_dl_tti_request_t + 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); + + //deallocate_nfapi_hi_dci0_request(subframe_buffer->hi_dci0_req, pnf_p7); + } + 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 0 + if(tx_slot_buffer->ue_release_req != 0) // TODO: check later if needed + { + if(pnf_p7->_public.ue_release_req) + (pnf_p7->_public.ue_release_req)(&(pnf_p7->_public), tx_slot_buffer->ue_release_req); + } + + else + { + //send dummy + if(pnf_p7->_public.ue_release_req && pnf_p7->_public.dummy_slot.ue_release_req) + { + pnf_p7->_public.dummy_slot.ue_release_req->sfn_sf = sfn_slot_tx; + (pnf_p7->_public.ue_release_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_slot.ue_release_req); + } + } + #endif + //TODO: add deallocate fns for the new structs + 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 + // 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 + if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); + return -1; + } + +#if 1 + // save the curren time and 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); + + // If the subframe_buffer has been configured + if(pnf_p7->_public.subframe_buffer_size != 0) + { + + // apply the shift to the incoming sfn_sf + if(pnf_p7->sfn_sf_shift != 0) + { + int32_t sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf); + + int32_t shifted_sfn_sf = sfn_sf_dec += pnf_p7->sfn_sf_shift; + + // adjust for wrap-around + if(shifted_sfn_sf < 0) + shifted_sfn_sf += NFAPI_MAX_SFNSFDEC; + else if(shifted_sfn_sf > NFAPI_MAX_SFNSFDEC) + shifted_sfn_sf -= NFAPI_MAX_SFNSFDEC; + + NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/sf (%d -> %d)\n", pnf_p7->sfn_sf_shift, NFAPI_SFNSF2DEC(sfn_sf), shifted_sfn_sf); + sfn_sf = shifted_sfn_sf; + + // + // DJP - why does the shift not apply to pnf_p7->sfn_sf??? + // + + pnf_p7->sfn_sf_shift = 0; + } + + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + nfapi_pnf_p7_subframe_buffer_t* subframe_buffer = &(pnf_p7->subframe_buffer[buffer_index]); + + uint8_t tx_buffer_index = tx_sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + nfapi_pnf_p7_subframe_buffer_t* tx_subframe_buffer = &(pnf_p7->subframe_buffer[tx_buffer_index]); + + //printf("sfn_sf_dec:%d tx_sfn_sf_dec:%d\n", sfn_sf_dec, tx_sfn_sf_dec); + + if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d subframe_buffer->sfn_sf:%d tx_subframe_buffer->sfn_sf:%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->sfn_sf_shift, @@ -890,6 +1516,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,21 +1645,19 @@ uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy) } -// P7 messages -// -void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) +// 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_dl_config_request_t* req = allocate_nfapi_dl_config_request(pnf_p7); + 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_config_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_dl_tti_request structure\n"); return; } - int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_dl_config_request_t), &(pnf_p7->_public.codec_config)); + 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) { @@ -966,7 +1666,7 @@ void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n"); return; } - +#if 0 if ( 0 && (NFAPI_SFNSF2DEC(req->sfn_sf) % 100 ==0 || @@ -981,47 +1681,47 @@ void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ req->dl_config_request_body.number_pdsch_rnti, req->dl_config_request_body.transmission_power_pcfich ); +#endif - if(is_p7_request_in_window(req->sfn_sf, "dl_config_request", pnf_p7)) + if(is_nr_p7_request_in_window(req->SFN,req->Slot, "dl_tti_request", pnf_p7)) { - uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); - uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + 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_CONFIG_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index); + //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->subframe_buffer[buffer_index].dl_config_req != 0) + if(pnf_p7->slot_buffer[buffer_index].dl_tti_req != 0) { - NFAPI_TRACE(NFAPI_TRACE_NOTE, "%s() is_p7_request_in_window()=TRUE buffer_index occupied - free it first sfn_sf:%d buffer_index:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), buffer_index); + 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_config_request(pnf_p7->subframe_buffer[buffer_index].dl_config_req, pnf_p7); + 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->subframe_buffer[buffer_index].sfn_sf = req->sfn_sf; - pnf_p7->subframe_buffer[buffer_index].dl_config_req = req; + 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_conf_ontime++; - + 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_config_request(req, pnf_p7); + 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_conf_late++; - } - + pnf_p7->stats.dl_tti_late++; + } if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0) { NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n"); @@ -1030,24 +1730,25 @@ void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack dl_config_req"); - deallocate_nfapi_dl_config_request(req, pnf_p7); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack dl_tti_req"); + deallocate_nfapi_dl_tti_request(req, pnf_p7); } } -void pnf_handle_ul_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) + +void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "UL_CONFIG.req Received\n"); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req Received\n"); - nfapi_ul_config_request_t* req = allocate_nfapi_ul_config_request(pnf_p7); + nfapi_dl_config_request_t* req = allocate_nfapi_dl_config_request(pnf_p7); if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_ul_config_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_dl_config_request structure\n"); return; } - int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_ul_config_request_t), &(pnf_p7->_public.codec_config)); + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_dl_config_request_t), &(pnf_p7->_public.codec_config)); if(unpack_result == 0) { @@ -1057,10 +1758,174 @@ void pnf_handle_ul_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ return; } - if(is_p7_request_in_window(req->sfn_sf, "ul_config_request", pnf_p7)) - { - uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); - uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + 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 + ); + + if(is_p7_request_in_window(req->sfn_sf, "dl_config_request", pnf_p7)) + { + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; + + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + + NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_CONFIG_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index); + + // if there is already an dl_config_req make sure we free it. + if(pnf_p7->subframe_buffer[buffer_index].dl_config_req != 0) + { + NFAPI_TRACE(NFAPI_TRACE_NOTE, "%s() is_p7_request_in_window()=TRUE buffer_index occupied - free it first sfn_sf:%d buffer_index:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), 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_config_request(pnf_p7->subframe_buffer[buffer_index].dl_config_req, pnf_p7); + } + + // saving dl_config_request in subframe buffer + pnf_p7->subframe_buffer[buffer_index].sfn_sf = req->sfn_sf; + pnf_p7->subframe_buffer[buffer_index].dl_config_req = req; + + pnf_p7->stats.dl_conf_ontime++; + + } + else + { + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "NOT storing dl_config_req SFN/SF %d\n", req->sfn_sf); + deallocate_nfapi_dl_config_request(req, pnf_p7); + + if(pnf_p7->_public.timing_info_mode_aperiodic) + { + pnf_p7->timing_info_aperiodic_send = 1; + } + + pnf_p7->stats.dl_conf_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_config_req"); + deallocate_nfapi_dl_config_request(req, pnf_p7); + } +} + + +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"); + + nfapi_ul_config_request_t* req = allocate_nfapi_ul_config_request(pnf_p7); + + if(req == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_ul_config_request structure\n"); + return; + } + + int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_ul_config_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_p7_request_in_window(req->sfn_sf, "ul_config_request", pnf_p7)) + { + uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf); + uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size; struct timespec t; clock_gettime(CLOCK_MONOTONIC, &t); @@ -1107,7 +1972,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 +2112,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,9 +2455,32 @@ uint32_t calculate_t2(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_t return t2; } -uint32_t calculate_t3(uint16_t sfn_sf, uint32_t sf_start_time_hr) +uint32_t calculate_nr_t2(uint32_t now_time_hr, 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 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(); uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr); @@ -1448,6 +2489,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 +2550,62 @@ 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); +// ul_node_sync.t2 = ul_node_sync.t1 + 10; +// ul_node_sync.t3 = ul_node_sync.t2 + 10; // hardcoded - gokul + + 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 +2636,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 +2651,92 @@ 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; + + case NFAPI_UE_RELEASE_REQUEST: + pnf_handle_ue_release_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_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; + #if 0 + case NFAPI_DL_CONFIG_REQUEST: + pnf_handle_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + case NFAPI_UL_CONFIG_REQUEST: + pnf_handle_ul_config_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + + case NFAPI_HI_DCI0_REQUEST: + pnf_handle_hi_dci0_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + + case NFAPI_TX_REQUEST: + pnf_handle_tx_request(pRecvMsg, recvMsgLen, pnf_p7); + break; + #endif case NFAPI_LBT_DL_CONFIG_REQUEST: pnf_handle_lbt_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7); break; @@ -1674,11 +2866,120 @@ 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; struct sockaddr_in remote_addr; socklen_t remote_addr_size = sizeof(remote_addr); + remote_addr.sin_family = 2; // Gokul - hardcoded do { @@ -1708,6 +3009,70 @@ 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) + { + // 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); +} + +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; // Gokul - 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) @@ -1735,6 +3100,7 @@ void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time) while(recvfrom_result > 0); } + int pnf_p7_message_pump(pnf_p7_t* pnf_p7) { @@ -1786,7 +3152,8 @@ 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 = htons(pnf_p7->_public.local_p7_port); Gokul + addr.sin_port = pnf_p7->_public.local_p7_port; if(pnf_p7->_public.local_p7_addr == 0) { @@ -1827,6 +3194,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 +3215,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 +3241,144 @@ 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 = htons(pnf_p7->_public.local_p7_port); Gokul + 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 24e73ae9b3c6fb54efd362b6ed855a941b6cb932..efcb60ce9632e366927ca4cb6c4af18bdcc28775 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 d2ab031ad4708000942e490df8a0cd0b64276bb8..bd6bedbea546c67e9e8a133b7b26b586f13a23fe 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 4fd8d2b91d6e1ec63b08e8ffb3a4ba0786c30b53..b16b842606dab220fc4c63e8c1f1786b2a4b491b 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 fc2ab4e6b5382bd282d08d1a20290b98b0e65f88..ad1c5e7944295028eab74897ae8db264d836e989 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 5abf6b75c39c469553b1be44500e575e95bbb8de..518b01864e5f60d4d5b041bf93a8a0b84c2c5e5d 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 6800ee21d202cbae1c69ae5335ab7fbae3efd7a0..30c2f4c03c119c0e521d28425011a6cb5fc447ca 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf.c +++ b/nfapi/open-nFAPI/vnf/src/vnf.c @@ -21,9 +21,12 @@ #include <arpa/inet.h> #include <stdlib.h> #include <string.h> +#include <stdio.h> #include <errno.h> #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,122 @@ 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_START_RESPONSE: + vnf_nr_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_STOP_RESPONSE: + vnf_handle_stop_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_MEASUREMENT_RESPONSE: + vnf_handle_measurement_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_RSSI_RESPONSE: + vnf_handle_rssi_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_RSSI_INDICATION: + vnf_handle_rssi_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_CELL_SEARCH_RESPONSE: + vnf_handle_cell_search_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_CELL_SEARCH_INDICATION: + vnf_handle_cell_search_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_BROADCAST_DETECT_RESPONSE: + vnf_handle_broadcast_detect_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_BROADCAST_DETECT_INDICATION: + vnf_handle_broadcast_detect_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE: + vnf_handle_system_information_schedule_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION: + vnf_handle_system_information_schedule_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_SYSTEM_INFORMATION_RESPONSE: + vnf_handle_system_information_response(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_SYSTEM_INFORMATION_INDICATION: + vnf_handle_system_information_indication(pRecvMsg, recvMsgLen, config, p5_idx); + break; + + case NFAPI_NMM_STOP_RESPONSE: + vnf_handle_nmm_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 +1287,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; i<message_size; i++){ + printf("%d", read_buffer[i]); + } + printf("\n"); + + vnf_nr_handle_p4_p5_message(read_buffer, message_size, pnf->p5_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 +1516,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; i<message_size; i++){ + printf("%d", read_buffer[i]); + } + printf("\n"); + vnf_handle_p4_p5_message(read_buffer, message_size, pnf->p5_idx, config); } else @@ -1051,6 +1549,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; i<len; i++){ + printf("%d", *(uint8_t *)(msg + i)); + } + printf("\n"); + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s len:%d stream:%d\n", __FUNCTION__, len, stream); int result = sctp_sendmsg(pnf->p5_sock, msg, len, (struct sockaddr*)&pnf->p5_pnf_sockaddr, sizeof(pnf->p5_pnf_sockaddr),1, 0, stream, 0, 4); @@ -1071,6 +1575,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 59d7f3eb4fb1dd17ae8331b9ec5b020849053000..084c4fa48547dcb1958dd806bed057eb2cea4a04 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 cff24500b6c57d2bfcd3009a524ba46caf872415..ffbc5819bc4826eaf0a349edd680e4860c283131 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 t4 = (NFAPI_SFNSLOT2DEC(sfn,slot) * 500) + slot_time_us; + + return t4; -uint32_t calculate_transmit_timestamp(uint16_t sfn_sf, uint32_t sf_start_time_hr) +} + + +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,80 +1454,593 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) } } -void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) -{ - if (pRecvMsg == NULL || vnf_p7 == NULL) +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_timing_info: NULL parameters\n"); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_ul_node_sync: NULL parameters\n"); return; } - nfapi_timing_info_t ind; - if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_timing_info_t), &vnf_p7->_public.codec_config) < 0) + 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 timing_info\n"); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack ul_node_sync\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); + //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_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); + 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); - // Panos: Careful here!!! Modification of the original nfapi-code - //if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1) - if (vnf_pnf_sfnsf_delta>0 || vnf_pnf_sfnsf_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_sfnsf_delta, NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), NFAPI_SFNSF2DEC(ind.last_sfn_sf)); - // Panos: Careful here!!! Modification of the original nfapi-code - vnf_p7->p7_connections[0].sfn_sf = ind.last_sfn_sf; - } - } -} + 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; -void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) -{ - nfapi_p7_message_header_t header; + // divide by 2 using shift operator + uint32_t latency = (tx_2_rx - pnf_proc_time) >> 1; - // validate the input params - if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL) + if(!(phy->filtered_adjust)) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); - return; - } + phy->latency[phy->min_sync_cycle_count] = latency; - // 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; + //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); } - - // ensure the message is sensible - if (recvMsgLen < 8 || pRecvMsg == NULL) + else { - NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen); - return; - } + phy->latency[phy->min_sync_cycle_count] = latency; - switch (header.message_id) - { - case NFAPI_UL_NODE_SYNC: - vnf_handle_ul_node_sync(pRecvMsg, recvMsgLen, vnf_p7); - break; + //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; + } - case NFAPI_TIMING_INFO: - vnf_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; + 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.t1<phy->previous_t1), (ind.t2<phy->previous_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) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_timing_info: NULL parameters\n"); + return; + } + + nfapi_timing_info_t ind; + if(nfapi_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); + + //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) + if (vnf_pnf_sfnsf_delta>0 || vnf_pnf_sfnsf_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_sfnsf_delta, NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), NFAPI_SFNSF2DEC(ind.last_sfn_sf)); + // Panos: Careful here!!! Modification of the original nfapi-code + vnf_p7->p7_connections[0].sfn_sf = ind.last_sfn_sf; + } + } +} + + +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; + + // 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_UL_NODE_SYNC: + vnf_handle_ul_node_sync(pRecvMsg, recvMsgLen, vnf_p7); + break; + + case NFAPI_TIMING_INFO: + vnf_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_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); @@ -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 a0efeeb5f4dbff9f123c5715bd02266efcccfecb..cac462b2c25fdbb334096326a4dfae036c7c6c5e 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,371 @@ 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); + //printf("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 + // CHANGE - gokul + 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); + //printf("\nsfn:%d, slot:%d\n current time:%d.%d",curr->sfn,curr->slot,current_time.tv_sec, current_time.tv_nsec); //remove later - gokul + //printf("next slot will start at %d.%d\n",current_time.tv_sec, current_time.tv_nsec); + curr = curr->next; + } + //send_mac_subframe_indications(vnf_p7); + 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 +774,7 @@ if (selectRetval==-1 && errno == 22) return 0; } + int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config) { if(config == 0) @@ -434,17 +801,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 +858,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 +878,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 +894,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/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 2c7e3e88eb5b06cc8c9a03f7e8713266687b06f0..1fb33152ff772e59324c721f4c82374805175ff8 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -81,7 +81,6 @@ l1_north_init_eNB () { return(0); } - void phy_config_request(PHY_Config_t *phy_config) { uint8_t Mod_id = phy_config->Mod_id; int CC_id = phy_config->CC_id; @@ -573,6 +572,7 @@ void phy_free_lte_eNB(PHY_VARS_eNB *eNB) { for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) eNB->UE_stats_ptr[UE_id] = NULL; } + void install_schedule_handlers(IF_Module_t *if_inst) { if_inst->PHY_config_req = phy_config_request; if_inst->schedule_response = schedule_response; diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c index f5b7a6c7e86022f5a2e8e389e78957a8830de204..a5790ed23dc8acf2ca51e12918ac2c3bb166bb1c 100644 --- a/openair1/PHY/INIT/lte_parms.c +++ b/openair1/PHY/INIT/lte_parms.c @@ -183,6 +183,7 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms, } + void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms) { LOG_I(PHY,"frame_parms->N_RB_DL=%d\n",frame_parms->N_RB_DL); LOG_I(PHY,"frame_parms->N_RB_UL=%d\n",frame_parms->N_RB_UL); diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 49ec60c94beceffcf324f613ebb84a7798f21958..7e6a6dda3ecfd830539277e1ce2c31e56f2e2693 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -389,6 +389,13 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL; */ } + +//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) { @@ -467,7 +474,10 @@ 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<<gNB_config->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]; + //fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + lte_frame_type_t frame_type = 0; // FDD + + get_band(fp->dl_CarrierFreq,&fp->nr_band,&dlul_offset,&frame_type); //RC.nrmac[Mod_id] cannot be accessed in NFAPI get_delta_duplex(fp->nr_band, gNB_config->ssb_config.scs_common.value, &dlul_offset); dlul_offset *= 1000; @@ -507,6 +517,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { 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/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 60b28d4ad18da254f99854369c028e134d014c1a..19126382e70e9511a689304f9c586f2fb1e3efc0 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -419,7 +419,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, int sample_offset, int no_prefix) { - int32_t slot_offset, rxdata_offset; + int32_t slot_offset, rxdata_offset; unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index c5bba196a54cf47483abac7746b75dcfb49608c6..f21d4b3d23f15dcf22e8c9f08985da3324b4ccaf 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -55,6 +55,8 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, void init_scrambling_luts(void); void nr_generate_modulation_table(void); +void nr_generate_modulation_table(void); + extern __m64 byte2m64_re[256]; extern __m64 byte2m64_im[256]; extern __m128i byte2m128i[256]; diff --git a/openair1/PHY/NR_REFSIG/scrambling_luts.c b/openair1/PHY/NR_REFSIG/scrambling_luts.c index 3509291e42d918443f0f5e4934ec72e06b2e5346..2a37a125390e1ff63ee85bf7adea5201bfe14195 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 cc71e9dd97e21b2142d0e3757a4e28136838539c..70d4e3041ff847161f5a7c193dadddf756a6d5a7 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -93,11 +93,12 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, } else cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB; - for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) { - /*The coreset is initialised - * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0 - * or the rb_offset for other coresets - * in time: by its first slot and its first symbol*/ + volatile int temp = pdcch_pdu_rel15->numDlDci; + for (volatile int d=0;d < temp;d++) { + //The coreset is initialised + //in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0 + //or the rb_offset for other coresets + //in time: by its first slot and its first symbol cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex; cset_nsymb = pdcch_pdu_rel15->DurationSymbols; @@ -179,7 +180,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, uint8_t reg_idx0 = pdcch_pdu_rel15->dci_pdu.CceIndex[d]*NR_NB_REG_PER_CCE; uint8_t nb_regs = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*NR_NB_REG_PER_CCE; - /*Mapping the encoded DCI along with the DMRS */ + //Mapping the encoded DCI along with the DMRS for (int reg_idx=reg_idx0; reg_idx<(nb_regs+reg_idx0); reg_idx++) { k = cset_start_sc + (12*reg_idx/cset_nsymb); @@ -249,3 +250,6 @@ void nr_generate_dci_top(PHY_VARS_gNB *gNB, nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms); } + + + diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index 2b64a3062cc6f449ad126c5a80cf91e7c2f3bbaf..f6e5b4db2073000ac9a77d6ba0afc760cc40403c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -203,7 +203,6 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_r return ret; }*/ int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type) { - uint16_t i; int16_t first_free_index=-1; @@ -227,7 +226,11 @@ void nr_fill_dci(PHY_VARS_gNB *gNB, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu_rel15; NR_gNB_DLSCH_t *dlsch; - + for(int i=0;i<NUMBER_OF_NR_PDCCH_MAX;i++) + { + gNB->pdcch_pdu[i].frame=-1; + } + int pdcch_id = find_nr_pdcch(frame,slot,gNB,SEARCH_EXIST_OR_FREE); AssertFatal(pdcch_id>=0 && pdcch_id<NUMBER_OF_NR_PDCCH_MAX,"Cannot find space for PDCCH, exiting\n"); memcpy((void*)&gNB->pdcch_pdu[pdcch_id].pdcch_pdu,(void*)pdcch_pdu,sizeof(*pdcch_pdu)); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index 5ce2c45a7dd94f4dcd4a133190fe2fdbd37b5416..1b70ce47dc415631186f10e5142ff3bf862003f2 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -285,7 +285,7 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &pdsch_pdu->pdsch_pdu_rel15; - int dlsch_id = find_nr_dlsch(rel15->rnti,gNB,SEARCH_EXIST); + int dlsch_id = find_nr_dlsch(pdsch_pdu->pdsch_pdu_rel15.rnti,gNB,SEARCH_EXIST); AssertFatal( (dlsch_id>=0) && (dlsch_id<NUMBER_OF_NR_DLSCH_MAX), "illegal or no dlsch_id found!!! rnti %04x dlsch_id %d\n",rel15->rnti,dlsch_id); NR_gNB_DLSCH_t *dlsch = gNB->dlsch[dlsch_id][0]; diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 5228cad98c870a27abc99382367478c7234edeb4..90d69ba5468c21abc01f1442a71f1219f3961da2 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -160,6 +160,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, nfapi_nr_pusch_pdu_t *pusch_pdu, NR_DL_FRAME_PARMS *frame_parms); + void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, NR_gNB_ULSCH_t **ulsch_gNB, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 1372250aca76ff9f4f16381b5b93421866bd39dc..f4f433f1ebef1993e2da3d0ca24cb8be9f199806 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -317,6 +317,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, } } + void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, NR_gNB_ULSCH_t **ulsch_gNB, diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 83a66b55fb2c9d9e1709c07c6a47db8701084628..6cd2fc72aeff78159eece33b08784a5cf69f218a 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -1657,5 +1657,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, if (pucch_pdu->bit_len_csi_part2>0) { uci_pdu->pduBitmap|=8; } + + if (pucch_pdu->bit_len_csi_part2>0) { + uci_pdu->pduBitmap|=8; + } + } diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 27765a854810ba30733b5cc6ffef7ac9f640c5ac..5a04e3c836f7273621199208d8f2264ea0f16717 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -99,7 +99,6 @@ #define NB_RX_ANTENNAS_MAX 64 - typedef enum {TDD=1,FDD=0} lte_frame_type_t; typedef enum {EXTENDED=1,NORMAL=0} lte_prefix_type_t; diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 96a073fbb8ca86baf98bfa5f12f1c529d76e2c51..dcab2156a618c1de5383f2344db7c2703a4a16d8 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -101,8 +101,6 @@ void handle_nfapi_hi_dci0_mpdcch_dci_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, // copy dci configuration in to eNB structure fill_mpdcch_dci0(eNB,proc,&pdcch_vars->mdci_alloc[pdcch_vars->num_dci], &hi_dci0_config_pdu->mpdcch_dci_pdu); } - - 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) { LTE_eNB_PHICH *phich = &eNB->phich_vars[subframe&1]; diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h index 4da1fa63ec54b5493e520b018b4dbc78ecc157c0..6b9121e17ff4acc088552ab1458431e8fd75a039 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 0000000000000000000000000000000000000000..d857f0acac7e8243d5f36fcbfb3c68d25dfe43d2 --- /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){} +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){} + +uint8_t slot_ahead=6; +uint8_t nfapi_mode=0; +NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {} + +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 0000000000000000000000000000000000000000..f3783c00f4428dbe80a5f7636ce7f07464366af2 --- /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){} +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){} + +uint8_t slot_ahead=6; +uint8_t nfapi_mode=0; +NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {} + +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 84490bfad451fb82fad288d0fdcba7088a87ea99..225a357c55189cd5d199767aa6863465436c3bf2 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" + +int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_tti_request_t *dl_config_req); +int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req); +int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req); +int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req); extern uint8_t nfapi_mode; @@ -126,7 +132,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; @@ -137,6 +143,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ frame_t frame = Sched_INFO->frame; sub_frame_t slot = Sched_INFO->slot; + //LOG_I(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d/%d\n",frame,slot); + + AssertFatal(RC.gNB!=NULL,"RC.gNB is null\n"); AssertFatal(RC.gNB[Mod_id]!=NULL,"RC.gNB[%d] is null\n",Mod_id); @@ -168,7 +177,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ switch (dl_tti_pdu->PDUType) { case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: gNB->pbch_configured=1; - + if(nfapi_mode != 2) handle_nr_nfapi_ssb_pdu(gNB,frame,slot, dl_tti_pdu); @@ -176,7 +185,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 != 2) handle_nfapi_nr_pdcch_pdu(gNB, frame, slot, &dl_tti_pdu->pdcch_pdu); @@ -193,17 +202,19 @@ 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 != 2) 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)); - - for (int i=0;i<number_ul_dci_pdu;i++) { + if(nfapi_mode != 2) + for (int i=0;i<number_ul_dci_pdu;i++) { handle_nfapi_nr_ul_dci_pdu(gNB, frame, slot, &UL_dci_req->ul_dci_pdu_list[i]); } +if(nfapi_mode != 2) 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: @@ -222,4 +233,29 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ break; } } + +if(nfapi_mode != 0 && number_ul_tti_pdu>0) +{ + oai_nfapi_ul_tti_req(UL_tti_req); } + + if (nfapi_mode != 0 && Sched_INFO->UL_dci_req->numPdus!=0) + { + oai_nfapi_ul_dci_req(Sched_INFO->UL_dci_req); + }//Only DL + + if (nfapi_mode != 0) + { 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_nr_dl_config_req(Sched_INFO->DL_req); + } + if (Sched_INFO->TX_req->Number_of_PDUs > 0) + { + oai_nfapi_tx_data_req(Sched_INFO->TX_req); + } + + } + + } diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h index d66d6e7b24201d5db0f8149ba5ef356555f13fb0..ed90b9870b8bb4b5e0de4d58955cb4e9663f560f 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 a78b1f48056ffa09963ef58045b1f7fd06852d30..5a3a235fad3d1e2f4a5a4eb0ca22367f48ffda5e 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -121,6 +121,12 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { 1, fp->nb_prefix_samples, CYCLIC_PREFIX); + apply_nr_rotation(fp, + (int16_t*)&ru->common.txdata[aa][slot_offset], + slot, + idx_sym, + 1, + fp->ofdm_symbol_size+fp->nb_prefix_samples); slot_offset += fp->nb_prefix_samples+fp->ofdm_symbol_size; } else { @@ -130,6 +136,12 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { 1, fp->nb_prefix_samples0, CYCLIC_PREFIX); + apply_nr_rotation(fp, + (int16_t*)&ru->common.txdata[aa][slot_offset], + slot, + 0, + 1, + fp->ofdm_symbol_size+fp->nb_prefix_samples0); slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size; } } diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c index 3864b2fcb20a0dc8bec2718984bcf4348e861233..6535f8bb1b17f5619a136e51a60c2e5c631bbb71 100644 --- a/openair1/SCHED_NR/phy_frame_config_nr.c +++ b/openair1/SCHED_NR/phy_frame_config_nr.c @@ -116,7 +116,9 @@ int set_tdd_config_nr( nfapi_nr_config_request_scf_t *cfg, while(slot_number != nb_slots_to_set) { if(nrofDownlinkSlots != 0) { for (int number_of_symbol = 0; number_of_symbol < nrofDownlinkSlots*NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) { - cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.value= 0; + cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.value= 0; // was 0, made 10 to check + // cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.tl.tag= NFAPI_NR_CONFIG_SLOT_CONFIG_TAG; + if((number_of_symbol+1)%NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) slot_number++; @@ -308,17 +310,18 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) { * *********************************************************************/ -int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot) { - /* for FFD all slot can be considered as an uplink */ +int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) { + /* for FDD all slot can be considered as an uplink */ int mu = cfg->ssb_config.scs_common.value,check_slot=0; if (cfg->cell_config.frame_duplex_type.value == FDD) { return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT ); } +#if 1 // Hardcoding, change later if (nr_frame%2 == 0) { for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) { - if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) { + if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) { check_slot++; } } @@ -330,7 +333,7 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot check_slot = 0; for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) { - if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) { + if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) { check_slot++; } } @@ -342,7 +345,7 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot } } else { for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) { - if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) { + if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) { check_slot++; } } @@ -354,7 +357,7 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot check_slot = 0; for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) { - if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) { + if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) { check_slot++; } } @@ -365,6 +368,11 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot return (NR_MIXED_SLOT); } } +#else + return (NR_DOWNLINK_SLOT); +#endif + + } /******************************************************************* diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6b5c1a9b22df56e12fa1336148eb921562ec0b75..f969fa11fba3a92337af47952aca459fb6ab33cb 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -138,6 +138,9 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame,int slot, int do_meas) { + // struct timespec time; + // clock_gettime(CLOCK_MONOTONIC, &time); + // LOG_I(PHY,"\nphy_procedures_gNB_TX frame tx %d slot tx %d time %d.%d\n",frame,slot,time.tv_sec,time.tv_nsec); int aa; NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index c600343ed019b9a8f29a0fa9423a796891d40dbd..1f7f7e93ebf8ab67be163932d387bb4ca89a44e8 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -236,6 +236,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ } ul_config->number_pdus = 0; } + } return 0; } diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 821ac75a648ba92b5b011152f0d4728bc268f2b2..bb322e20e80750204f72bdf8ac70782d3a8830a5 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -74,6 +74,7 @@ RAN_CONTEXT_t RC; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int sf_ahead=4 ; +int slot_ahead=6 ; int sl_ahead=0; double cpuf; uint8_t nfapi_mode = 0; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 5f74d6121fbdea0ca505a32e182c76312aa04832..5c33c79488bc34cb486d39d9186d41d52c1812b9 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -427,7 +427,7 @@ void RCconfig_NR_L1(void) { 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++) @@ -497,8 +497,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)); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index cc6b1b9de3aa77904b8d9cdaec5b742adbc05fb2..2e00c6ebe30ff89bf65b87cb90bf847854f4ccc9 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2918,3 +2918,46 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config, //printf("[MAC] PTRS is set K= %u L= %u\n", *K_ptrs,1<<*L_ptrs); return valid; } +void get_band(uint64_t downlink_frequency, + uint16_t *current_band, + int32_t *current_offset, + lte_frame_type_t *current_type) +{ + int ind; + uint64_t center_frequency_khz; + uint64_t center_freq_diff_khz; + uint64_t dl_freq_khz = downlink_frequency/1000; + + center_freq_diff_khz = 999999999999999999; // 2^64 + *current_band = 0; + + for ( ind=0; + ind < sizeof(nr_bandtable) / sizeof(nr_bandtable[0]); + ind++) { + + LOG_I(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min,nr_bandtable[ind].ul_min); + + if ( nr_bandtable[ind].dl_min <= dl_freq_khz && nr_bandtable[ind].dl_max >= dl_freq_khz ) { + + center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min)/2; + if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){ + *current_band = nr_bandtable[ind].band; + *current_offset = (nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min)*1000; + center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz); + + if (*current_offset == 0) + *current_type = TDD; + else + *current_type = FDD; + } + } + } + + LOG_I( PHY, "DL frequency %"PRIu64": band %d, frame_type %d, UL frequency %"PRIu64"\n", + downlink_frequency, *current_band, *current_type, downlink_frequency+*current_offset); + + AssertFatal(*current_band != 0, + "Can't find EUTRA band for frequency %lu\n", downlink_frequency); +} + + diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index d4cc1bd2a74754bc6505e01d27efa31b5cebf721..11544afd42bcfe25b314a7d5471464ac8782d98b 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -185,4 +185,5 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config, uint8_t *K_ptrs, uint8_t *L_ptrs,uint8_t *portIndex, uint8_t *nERatio,uint8_t *reOffset, uint8_t NrOfSymbols); +void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type); #endif diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 34b6d801c5752f7852b94d08620c5487f9856ee2..cc26184c134ec645b11618a28e40d9d30df83bd3 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -100,7 +100,6 @@ void nr_get_prach_resources(module_id_t mod_id, //////////* UE Random Access Resource Selection *////////// /////////////////////////////////////////////////////////// - // todo: // - switch initialisation cases // -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index ab49fcdc8c8947950999ba463f5cce45ddc8b447..addba1a6c228bbf22eea54b46b6ab0ba8cfe95b0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -261,6 +261,7 @@ 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->ssb_table.ssb_mask_list[1].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG; cfg->num_tlv++; cfg->carrier_config.num_tx_ant.value = pdsch_AntennaPorts; @@ -279,6 +280,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm cfg->num_tlv++; cfg->num_tlv++; + // TDD Table Configuration //cfg->tdd_table.tdd_period.value = scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity; cfg->tdd_table.tdd_period.tl.tag = NFAPI_NR_CONFIG_TDD_PERIOD_TAG; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index e4c2e11d7dd40b3833474f8690935d3a50ded6f0..d5c17a3bd4eada0c3d517415da12fb28c794ce0d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -413,6 +413,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } const uint64_t dlsch_in_slot_bitmap = (1 << 1) | (1 << 2); + //const uint64_t dlsch_in_slot_bitmap = (1 << 2); const uint64_t ulsch_in_slot_bitmap = (1 << 8); memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index a9839ed985b91abbaa325713b4d47681e908d62a..b8aa4223be73a77833272eac686ed529812917bd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -67,7 +67,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, unsigned char drx_cmd, unsigned char *ue_cont_res_id, unsigned short post_padding) { - gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu; unsigned char *dlsch_buffer_ptr = sdus_payload; uint8_t last_size = 0; @@ -699,7 +699,8 @@ void nr_schedule_ue_spec(module_id_t module_id, LOG_D(MAC, "Configuring DL_TX in %d.%d: random data\n", frame, slot); // fill dlsch_buffer with random data for (int i = 0; i < TBS; i++) - mac_sdus[i] = (unsigned char) (lrand48()&0xff); + mac_sdus[i] = (unsigned char) (lrand48()&0xff); + sdu_lcids[0] = 0x3f; // DRB sdu_lengths[0] = TBS - ta_len - 3; header_length_total += 2 + (sdu_lengths[0] >= 256); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index e14afacf097e5ce85fa935a3fa68c35a6351b7bd..2727fe24dbf6286b1ce6868e973856e5d2ced09e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -69,7 +69,6 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, uint8_t CC_id; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[0]; - nfapi_nr_dl_tti_request_body_t *dl_req; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu; nfapi_nr_pdu_t *TX_req; @@ -95,15 +94,13 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, LOG_D(MAC, "Scheduling common search space DCI type 1 dlBWP BW.firstRB %d.%d\n", dlBWP_carrier_bandwidth, NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275)); - - - dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; - dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + + dl_tti_pdcch_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]; memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); - dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1]; + 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,7 +235,7 @@ 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; @@ -258,7 +255,7 @@ void nr_preprocessor_phytest(module_id_t module_id, sub_frame_t slot, int num_slots_per_tdd) { - if (slot != 1) + if (slot != 2) return; /* only schedule in slot 1 for now */ NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; const int UE_id = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 76c9dedf30c64cc387f13bc0cc83df5b70f9db27..a90b4c7a179552fd4bdce3fe74f8dc1fc38af167 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -245,6 +245,7 @@ void nr_process_mac_pdu( } + break; default: @@ -351,7 +352,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n"); for (int i = 0; i < sdu_lenP ; i++) { //harq_process_ul_ue->a[i] = (unsigned char) rand(); @@ -359,7 +359,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, printf("%02x ",(unsigned char)sduP[i]); } printf("\n"); - #endif if (sduP != NULL){ @@ -420,3 +419,4 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } } + diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 656d1c3e7ca5436e286298140aaa5411d1310b8b..8e00bc090272354f192bc12a6c5d5d2c657c78d0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -435,6 +435,7 @@ typedef struct { int num_pdcch_cand[MAX_MOBILES_PER_GNB][MAX_NUM_CORESET]; // UE selected beam index uint8_t UE_beam_index[MAX_MOBILES_PER_GNB]; + } NR_UE_info_t; typedef void (*nr_pp_impl_dl)(module_id_t mod_id, diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 12ad6bf6a23a79e1899a008456a36940c592aee5..22843bb956a9aaa33da1fff8725b144a088484b0 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -2107,8 +2107,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/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 04b9e188e6a5b6028edb4bbd073dea34bd5e4064..53da4f594b367ff8903be61ff273fbc86c2a0ceb 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -196,7 +196,6 @@ int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) { //} // PDCP_USE_NETLINK //AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno)); - //AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno)); delNotifiedFIFO_elt (sdu_p); pdcp_nb_sdu_sent ++; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ca37026e54f5cfa03276e8f9cd14c502b218b194..2919c9debaf687d99b871a7e938f437e38e30c47 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -46,7 +46,6 @@ static uint64_t pdcp_optmask; /* rlc_data_req queue - begin */ /****************************************************************************/ - #include <pthread.h> /* NR PDCP and RLC both use "big locks". In some cases a thread may do diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index d98c603d78444f2951f2a47bf6413506a959ad83..f59b95d7dce79a1277a892ac4d2f75049ac9c1a2 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -775,6 +775,7 @@ void UL_indication(UL_IND_t *UL_info, L1_rxtx_proc_t *proc) { } } + IF_Module_t *IF_Module_init(int Mod_id) { AssertFatal(Mod_id<MAX_MODULES,"Asking for Module %d > %d\n",Mod_id,MAX_IF_MODULES); LOG_D(PHY,"Installing callbacks for IF_Module - UL_indication\n"); diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index b4a7f8c6e708653406f5286ed01a72e6642362a9..b4d7f0ea6e06f5a7237e1b83bd8bf1b95dd67582 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, @@ -1068,6 +1072,7 @@ void handle_nfapi_hi_dci0_hi_pdu( nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { } + void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, @@ -1126,3 +1131,4 @@ int l1_north_init_eNB(void) { void init_eNB_afterRU(void) { } + diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 18b7173a087f926517629e1ebc26f9928d90041e..d629ffe604859f4e7dd1bba59cef255e7d652da3 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -155,6 +155,7 @@ init_SI( LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE) { + LOG_I(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n", (int)configuration->N_RB_DL[CC_id]); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4); @@ -1061,6 +1062,7 @@ void release_UE_in_freeList(module_id_t mod_id) { memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); } } + /* for (i=0; i<MAX_MOBILES_PER_ENB; i++) { @@ -7913,6 +7915,7 @@ rrc_eNB_decode_dcch( } ue_context_p->ue_context.reestablishment_xid = -1; + } else { dedicated_DRB = 1; ue_context_p->ue_context.Status = RRC_RECONFIGURED; diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 11c13eda32fc6862275f0adb4c56b3ddae2252c2..7a4f13b7c16ebd12cc2ebeb1a3413f3f67b6329f 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -149,10 +149,11 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, carrier->MIB, 24); LOG_D(NR_RRC,"Encoded MIB for frame %d sfn_msb %d (%p), bits %lu\n",frameP,sfn_msb,carrier->MIB,enc_rval.encoded); + buffer_pP[0]=carrier->MIB[0]; buffer_pP[1]=carrier->MIB[1]; buffer_pP[2]=carrier->MIB[2]; - LOG_D(NR_RRC,"MIB PDU buffer_pP[0]=%x , buffer_pP[1]=%x, buffer_pP[2]=%x\n",buffer_pP[0],buffer_pP[1],buffer_pP[2]); + LOG_I(NR_RRC,"MIB PDU buffer_pP[0]=%x , buffer_pP[1]=%x, buffer_pP[2]=%x\n",buffer_pP[0],buffer_pP[1],buffer_pP[2]); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); return(3); @@ -191,4 +192,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/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index b5bcf09d478959994c80c034735876d8f3800932..ca6e3e55bf378b3dbea8a9f329a83431fbb393be 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -247,7 +247,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0; - 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; diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index 2f60e7dc49efe15a25325565744cd916744d3bdc..72ecff6b342f899afaad6ec619dae383e03fb8e2 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -275,7 +275,6 @@ void benetel_fh_if4p5_south_out(RU_t *ru, int slot, uint64_t timestamp) { - //printf("XXX benetel_fh_if4p5_south_out %d %d %ld\n", frame, slot, timestamp); benetel_eth_state_t *s = ru->ifdevice.priv; NR_DL_FRAME_PARMS *fp; diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index dd29d01fae751ebc527ea59dc1423ed29475150f..e136186bc9791d6cf6c91e984c156114b91fe965 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -72,6 +72,8 @@ int gpio789=0; extern int usrp_tx_thread; +extern int usrp_tx_thread; + typedef struct { diff --git a/targets/COMMON/create_nr_tasks.c b/targets/COMMON/create_nr_tasks.c new file mode 100644 index 0000000000000000000000000000000000000000..13f72b387665f5fda364660301a7b96d13946459 --- /dev/null +++ b/targets/COMMON/create_nr_tasks.c @@ -0,0 +1,111 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +# include "intertask_interface.h" +# include "create_nr_tasks.h" +# include "common/utils/LOG/log.h" + +# ifdef OPENAIR2 +#include "sctp_eNB_task.h" +#include "s1ap_eNB.h" +#include "nas_ue_task.h" +#include "udp_eNB_task.h" +#include "gtpv1u_eNB_task.h" +# if ENABLE_RAL +# include "lteRALue.h" +# include "lteRALenb.h" +# endif +#include "RRC/NR/nr_rrc_defs.h" +# endif +# include "gnb_app.h" + +extern int emulate_rf; + +int create_gNB_tasks(uint32_t gnb_nb) +{ + LOG_D(GNB_APP, "%s(gnb_nb:%d\n", __FUNCTION__, gnb_nb); + + itti_wait_ready(1); + if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { + LOG_E(PDCP, "Create task for L2L1 failed\n"); + return -1; + } + + if (gnb_nb > 0) { + // Last task to create, others task must be ready before its start + if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { + LOG_E(GNB_APP, "Create task for gNB APP failed\n"); + return -1; + } + } + + + if (EPC_MODE_ENABLED) { + if (gnb_nb > 0) { + /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { + LOG_E(SCTP, "Create task for SCTP failed\n"); + return -1; + } + + if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) { + LOG_E(S1AP, "Create task for S1AP failed\n"); + return -1; + }*/ + if(!emulate_rf){ + if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { + LOG_E(UDP_, "Create task for UDP failed\n"); + return -1; + } + } + + if (itti_create_task (TASK_GTPV1_U, >pv1u_eNB_task, NULL) < 0) { + LOG_E(GTPU, "Create task for GTPV1U failed\n"); + return -1; + } + } + + } + + /*if (gnb_nb > 0) { + // Last task to create, others task must be ready before its start + if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { + LOG_E(GNB_APP, "Create task for gNB APP failed\n"); + return -1; + } + }*/ + + + if (gnb_nb > 0) { + LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); + + if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { + LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); + return -1; + } + } + + + itti_wait_ready(0); + + return 0; +} +//#endif diff --git a/targets/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 0000000000000000000000000000000000000000..a6dfe4c74fd05d9276ae26e0c268c4c3ba86d2aa --- /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.1"; // 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 = 50002; // pnf p7 port + remote_n_portd = 50003; // 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 0000000000000000000000000000000000000000..367c2ff5303cd74a3be90762a17acc2ba61c3082 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf @@ -0,0 +1,290 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641032; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=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.1"; // vnf addr + local_s_portc = 50001; // vnf p5 port + remote_s_portc = 50000; // pnf p5 port [!] + local_s_portd = 50003; // vnf p7 port [!] + remote_s_portd = 50002; // 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/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 0d0dde4ac47a322cb436485326f5c911fa32bc90..14f82c37a4f5a510525dcb682ca239f8c3e03f36 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -566,6 +566,19 @@ int main ( int argc, char **argv ) /* Read configuration */ if (RC.nb_inst > 0) { read_config_and_init(); + init_pdcp(); + + if (create_tasks(1) < 0) { + printf("cannot create ITTI tasks\n"); + exit(-1); + } + + for (int enb_id = 0; enb_id < RC.nb_inst; enb_id++) { + MessageDef *msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ); + RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; + itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + } + node_type = RC.rrc[0]->node_type; } else { printf("RC.nb_inst = 0, Initializing L1\n"); RCconfig_L1(); @@ -580,28 +593,17 @@ int main ( int argc, char **argv ) RC.nb_L1_inst, RC.nb_RU, get_nprocs()); } - if (RC.nb_inst > 0) { - /* Start the agent. If it is turned off in the configuration, it won't start */ - for (i = 0; i < RC.nb_inst; i++) { - flexran_agent_start(i); - } + if (RC.nb_inst > 0) { + /* Start the agent. If it is turned off in the configuration, it won't start */ + if(NFAPI_MODE != NFAPI_MODE_PNF) + for (i = 0; i < RC.nb_inst; i++) { + flexran_agent_start(i); + } /* initializes PDCP and sets correct RLC Request/PDCP Indication callbacks * for monolithic/F1 modes */ - init_pdcp(); - - if (create_tasks(1) < 0) { - printf("cannot create ITTI tasks\n"); - exit(-1); - } - - for (int enb_id = 0; enb_id < RC.nb_inst; enb_id++) { - MessageDef *msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ); - RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; - itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - } - node_type = RC.rrc[0]->node_type; - } + + } if (RC.nb_inst > 0 && NODE_IS_CU(node_type)) { protocol_ctxt_t ctxt;