diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..9fd870b859 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +*.log +cmake_targets/log/ +cmake_targets/ran_build/ +common/utils/T/T_IDs.h +common/utils/T/T_messages.txt.h +common/utils/T/genids +common/utils/T/genids.o +targets/bin/ diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 0e9e4adf89..9a6f363954 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -35,6 +35,9 @@ def doFlexranCtrlTest = false // Location of the executor node def nodeExecutor = params.nodeExecutor +// VM Lockable resources +def vmResource = params.vmLockableResource + pipeline { agent { label nodeExecutor @@ -159,65 +162,81 @@ pipeline { stage ("Start VM -- basic-sim") { steps { + lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- gnb-usrp") { steps { + lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- nr-ue-usrp") { steps { + lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- enb-usrp") { steps { + lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- phy-sim") { steps { + lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- enb-ethernet") { steps { + lock (vmResource) { timeout (time: 7, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- ue-ethernet") { steps { + lock (vmResource) { timeout (time: 7, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- cppcheck") { steps { + lock (vmResource) { timeout (time: 7, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } @@ -288,11 +307,14 @@ pipeline { } stage ("Build UE-ethernet") { steps { + // This is typically the last one to finish. + lock (vmResource) { gitlabCommitStatus(name: "Build UE-ethernet") { timeout (time: 20, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } + } } } } @@ -354,6 +376,7 @@ pipeline { stages { stage ("Test physical simulators") { steps { + lock (vmResource) { script { timeout (time: 90, unit: 'MINUTES') { try { @@ -365,6 +388,7 @@ pipeline { } } } + } } } stage ("Build Flexran Controller") { @@ -372,6 +396,7 @@ pipeline { expression {doFlexranCtrlTest} } steps { + lock (vmResource) { script { timeout (time: 20, unit: 'MINUTES') { try { @@ -381,10 +406,12 @@ pipeline { } } } + } } } stage ("Test basic simulator") { steps { + lock (vmResource) { script { timeout (time: 30, unit: 'MINUTES') { try { @@ -396,10 +423,12 @@ pipeline { } } } + } } } stage ("Test L1 simulator") { steps { + lock (vmResource) { script { timeout (time: 30, unit: 'MINUTES') { try { @@ -411,10 +440,12 @@ pipeline { } } } + } } } stage ("Test RF simulator") { steps { + lock (vmResource) { script { timeout (time: 40, unit: 'MINUTES') { try { @@ -426,10 +457,12 @@ pipeline { } } } + } } } stage ("Test L2 simulator") { steps { + lock (vmResource) { script { timeout (time: 30, unit: 'MINUTES') { try { @@ -441,11 +474,14 @@ 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}" + } } } } diff --git a/ci-scripts/Jenkinsfile-tmp-full-ran b/ci-scripts/Jenkinsfile-tmp-full-ran index 15ad0379af..c3323f792d 100644 --- a/ci-scripts/Jenkinsfile-tmp-full-ran +++ b/ci-scripts/Jenkinsfile-tmp-full-ran @@ -266,6 +266,42 @@ pipeline { } stage('Log Collection') { parallel { + stage('Log Collection (eNB - Build)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m' + sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("build.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "build.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (OAI UE - Build)') { + steps { + echo '\u2705 \u001B[32mLog Collection (OAI UE - Build)\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=LogCollectBuild --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (UE - Build)\u001B[0m' + sh "sshpass -p \'${UE_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${UE_Username}@${params.UE_IPAddress}:${UE_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("build.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "build.log.${env.BUILD_ID}.zip" + } + } + } + } stage('Log Collection (eNB - Run)') { steps { withCredentials([ diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh index d47b90a9dd..3a2fcbb02c 100755 --- a/ci-scripts/checkCodingFormattingRules.sh +++ b/ci-scripts/checkCodingFormattingRules.sh @@ -59,7 +59,7 @@ if [ $# -eq 0 ] then echo " ---- Checking the whole repository ----" echo "" - NB_FILES_TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt --recursive *.c *.h | grep -c Formatted ` + NB_FILES_TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt --recursive *.c *.h | grep -c Formatted || true` echo "Nb Files that do NOT follow OAI rules: $NB_FILES_TO_FORMAT" echo $NB_FILES_TO_FORMAT > ./oai_rules_result.txt @@ -67,17 +67,17 @@ then awk '/#[ \t]*ifndef/ { gsub("^.*ifndef *",""); if (names[$1]!="") print "files with same {define ", FILENAME, names[$1]; names[$1]=FILENAME } /#[ \t]*define/ { gsub("^.*define *",""); if(names[$1]!=FILENAME) print "error in declaration", FILENAME, $1, names[$1]; nextfile }' `find openair* common targets executables -name *.h |grep -v LFDS` > header-files-w-incorrect-define.txt # Testing if explicit GNU GPL license banner - egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "General Public License" . > files-w-gnu-gpl-license-banner.txt + egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "General Public License" . | egrep -v "openair3/NAS/COMMON/milenage.h" > files-w-gnu-gpl-license-banner.txt # Looking at exotic/suspect banner LIST_OF_FILES_W_BANNER=`egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "Copyright|copyleft" .` if [ -f ./files-w-suspect-banner.txt ]; then rm -f ./files-w-suspect-banner.txt; fi for FILE in $LIST_OF_FILES_W_BANNER do - IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"` - IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE` - IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE` - IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_"` + IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true` + IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE || true` + IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE || true` + IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair3/NAS/COMMON/milenage.h" || true` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] @@ -178,7 +178,7 @@ do EXT="${filename##*.}" if [ $EXT = "c" ] || [ $EXT = "h" ] || [ $EXT = "cpp" ] || [ $EXT = "hpp" ] then - TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt $FULLFILE | grep -c Formatted ` + TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt $FULLFILE | grep -c Formatted || true` NB_TO_FORMAT=$((NB_TO_FORMAT + TO_FORMAT)) if [ $TO_FORMAT -ne 0 ] then @@ -186,15 +186,19 @@ do echo $FULLFILE >> ./oai_rules_result_list.txt fi # Testing if explicit GNU GPL license banner - egrep -i "General Public License" $FULLFILE >> files-w-gnu-gpl-license-banner.txt + GNU_EXCEPTION=`echo $FULLFILE | egrep -c "openair3/NAS/COMMON/milenage.h" || true` + if [ $GNU_EXCEPTION -eq 0 ] + then + egrep -il "General Public License" $FULLFILE >> files-w-gnu-gpl-license-banner.txt + fi # Looking at exotic/suspect banner - IS_BANNER=`egrep -i -c "Copyright|copyleft" $FULLFILE` + IS_BANNER=`egrep -i -c "Copyright|copyleft" $FULLFILE || true` if [ $IS_BANNER -ne 0 ] then - IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"` - IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE` - IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE` - IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_"` + IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true` + IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE || true` + IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE || true` + IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair3/NAS/COMMON/milenage.h" || true` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 4b6f5ad667..4ac1b0ea94 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -72,6 +72,9 @@ class OaiCiTest(): self.ADBCentralized = True self.testCase_id = '' self.testXMLfiles = [] + self.testUnstable = False + self.testMinStableId = '999999' + self.testStabilityPointReached = False self.desc = '' self.ping_args = '' self.ping_packetloss_threshold = '' @@ -211,7 +214,7 @@ class OaiCiTest(): logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', CONST.ALL_PROCESSES_OK, 'OAI UE') HTML.CreateHtmlTabFooter(False) - sys.exit(1) + self.ConditionalExit() def CheckFlexranCtrlInstallation(self,RAN,EPC): if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '': @@ -335,7 +338,7 @@ class OaiCiTest(): if (pStatus < 0): HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', pStatus) HTML.CreateHtmlTabFooter(False) - sys.exit(1) + self.ConditionalExit() UE_prefix = '' else: UE_prefix = 'NR ' @@ -719,7 +722,7 @@ class OaiCiTest(): logging.debug('Using the OAI EPC HSS: not implemented yet') HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) HTML.CreateHtmlTabFooter(False) - sys.exit(1) + self.ConditionalExit() else: SSH.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5) result = re.search('Allocated ipv4 addr: (?P[0-9\.]+) from Pool', SSH.getBefore()) @@ -1046,7 +1049,7 @@ class OaiCiTest(): if (pStatus < 0): HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) HTML.CreateHtmlTabFooter(False) - sys.exit(1) + self.ConditionalExit() multi_jobs = [] for device_id in self.UEDevices: p = Process(target = self.RebootUE_common, args = (device_id,)) @@ -1154,15 +1157,18 @@ class OaiCiTest(): self.UEDevicesRebootCmd.append(comma_split[5]) phone_list_file.close() + # better handling of the case when no UE detected + # Sys-exit is now dealt by the calling function if terminate_ue_flag == True: if len(self.UEDevices) == 0: logging.debug('\u001B[1;37;41m UE Not Found! \u001B[0m') - sys.exit(1) + return False if len(self.UEDevicesStatus) == 0: cnt = 0 while cnt < len(self.UEDevices): self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) cnt += 1 + return True def GetAllCatMDevices(self, terminate_ue_flag): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': @@ -1248,7 +1254,7 @@ class OaiCiTest(): if (pStatus < 0): HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) HTML.CreateHtmlTabFooter(False) - sys.exit(1) + self.ConditionalExit() multi_jobs = [] lock = Lock() status_queue = SimpleQueue() @@ -1386,7 +1392,14 @@ class OaiCiTest(): SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) SSH.command('cd scripts', '\$', 5) - ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + # In case of a docker-based deployment, we need to ping from the trf-gen container + launchFromTrfContainer = False + if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE): + launchFromTrfContainer = True + if launchFromTrfContainer: + ping_status = SSH.command('docker exec -it prod-trf-gen /bin/bash -c "ping ' + self.ping_args + ' ' + UE_IPAddress + '" 2>&1 | tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + else: + ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) else: cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' message = cmd + '\n' @@ -2028,7 +2041,8 @@ class OaiCiTest(): SSH.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) else: SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ls /data/local/tmp"\'', '\$', 60) - result = re.search('iperf3', SSH.getBefore()) + # DEBUG: disabling iperf3 usage for the moment + result = re.search('iperf4', SSH.getBefore()) if result is None: result = re.search('iperf', SSH.getBefore()) if result is None: @@ -2105,6 +2119,10 @@ class OaiCiTest(): launchFromEpc = True if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): launchFromEpc = False + # When using a docker-based deployment, IPERF client shall be launched from trf container + launchFromTrfContainer = False + if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE): + launchFromTrfContainer = True if launchFromEpc: SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) @@ -2129,7 +2147,16 @@ class OaiCiTest(): self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue,SSH) else: if launchFromEpc: - iperf_status = SSH.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + if launchFromTrfContainer: + if self.ueIperfVersion == self.dummyIperfVersion: + prefix = '' + else: + prefix = '' + if self.ueIperfVersion == '2.0.5': + prefix = '/iperf-2.0.5/bin/' + iperf_status = SSH.command('docker exec -it prod-trf-gen /bin/bash -c "' + prefix + 'iperf -c ' + UE_IPAddress + ' ' + modified_options + '" 2>&1 | tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + else: + iperf_status = SSH.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) else: if self.ueIperfVersion == self.dummyIperfVersion: prefix = '' @@ -3148,6 +3175,12 @@ class OaiCiTest(): HTML.CpuMHz[idx]=CpuMHz SSH.close() + def ConditionalExit(self): + if self.testUnstable: + if self.testStabilityPointReached or self.testMinStableId == '999999': + sys.exit(0) + sys.exit(1) + def ShowTestID(self): logging.debug('\u001B[1m----------------------------------------\u001B[0m') logging.debug('\u001B[1mTest ID:' + self.testCase_id + '\u001B[0m') diff --git a/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf index becd484c56..42cade271c 100644 --- a/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf +++ b/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf @@ -181,6 +181,7 @@ eNBs = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf index 7e4dfc6de6..51f7277267 100644 --- a/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf +++ b/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf @@ -181,6 +181,7 @@ eNBs = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf index b1c4774aba..9946713c3a 100644 --- a/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf +++ b/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf @@ -181,6 +181,7 @@ eNBs = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf index 49926c3e60..0c247e9ef9 100644 --- a/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf @@ -175,6 +175,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf index 673c506dfa..f560958e15 100644 --- a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf +++ b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf @@ -356,6 +356,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf index cf508a1e95..ba81f832db 100644 --- a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf @@ -177,6 +177,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf index d26ab5d1b4..79bbd7ee6f 100644 --- a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf @@ -178,6 +178,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 55127e1c53..b5fd1255bb 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -136,6 +136,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 88e4c88685..552dfd637b 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -136,6 +136,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf index 5794310fad..d95d2b6ac1 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -136,6 +136,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf index 5348c25c0e..e466a23ab0 100644 --- a/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf @@ -136,6 +136,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf index 7ea8839b8a..e3cdb033c9 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf @@ -173,6 +173,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf index 36f0fdf7b1..f95530b251 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf index b61201440b..eddb34a579 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index 8a2cedfd05..b5d7f35a76 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -181,6 +181,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf index b2d5801efc..19e4abdcb0 100755 --- a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf @@ -183,6 +183,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf index 08dd300329..67cc5706ae 100644 --- a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf index 371a6b4610..1b5376644b 100644 --- a/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf @@ -175,6 +175,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index aa03e91fd0..aeba400cad 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -45,8 +45,8 @@ gNBs = dl_carrierBandwidth = 106; #initialDownlinkBWP #genericParameters - # this is RBstart=0,L=50 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 13475; + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -59,7 +59,7 @@ gNBs = #initialULBWPmappingType #0=typeA,1=typeB initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 + #this is SS=1,L=13 initialDLBWPstartSymbolAndLength_0 = 40; initialDLBWPk0_1 = 0; @@ -74,7 +74,7 @@ gNBs = initialDLBWPk0_3 = 0; initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 + #this is SS=1,L=5 initialDLBWPstartSymbolAndLength_3 = 57; #uplinkConfigCommon @@ -89,7 +89,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 13475; + initialULBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -126,17 +126,17 @@ gNBs = # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # msg1_SubcarrierSpacing = 1, - # restrictedSetConfig # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) initialULBWPk2_0 = 6; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 6; + + initialULBWPk2_1 = 6; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; @@ -145,7 +145,7 @@ gNBs = initialULBWPmappingType_2 = 1; # this is SS=10 L=4 initialULBWPstartSymbolAndLength_2 = 52; - + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -204,6 +204,7 @@ gNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "192.168.12.26"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -249,7 +250,7 @@ RUs = ( eNB_instances = [0]; #beamforming 1x4 matrix: bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; - sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; } ); diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index 7a4b5f54c1..0d9691966b 100755 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -201,6 +201,7 @@ gNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -291,3 +292,6 @@ THREAD_STRUCT = ( rrc_log_verbosity ="medium"; }; +uicc: { +opc = "testopc"; +}; diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf index 163047d7b9..a4d8e007dc 100644 --- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf @@ -173,6 +173,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf index bb49d68bb4..458ab7cf89 100644 --- a/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf @@ -174,6 +174,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf index 2e211d86b8..e80ff2b9cb 100644 --- a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf @@ -174,6 +174,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/lte-tdd-basic-sim.conf b/ci-scripts/conf_files/lte-tdd-basic-sim.conf index ad7e9d9f86..f443a907f2 100644 --- a/ci-scripts/conf_files/lte-tdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-tdd-basic-sim.conf @@ -136,6 +136,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf b/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf index b3899fdb6a..502e3c548a 100644 --- a/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf +++ b/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf @@ -141,6 +141,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 0547590c29..2bf79a3d7e 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -139,6 +139,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 3441690e6d..6b0e7de659 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -139,6 +139,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf index 23709444bd..6b41d78506 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -139,6 +139,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf index 33d00b8908..5df8f16f78 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf index a939c66cba..ad753bb114 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf index 473496defa..dbe3aff3dc 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf b/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf index bf2db71152..640b85930a 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf @@ -144,6 +144,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "192.168.15.130"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf index 3bcd038d70..7fe682f29e 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf @@ -144,6 +144,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "127.0.0.3"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf index ad113d0ffc..281f7433af 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf @@ -174,6 +174,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/cppcheck_suppressions.list b/ci-scripts/cppcheck_suppressions.list index 4b9fb97427..f8438a4276 100644 --- a/ci-scripts/cppcheck_suppressions.list +++ b/ci-scripts/cppcheck_suppressions.list @@ -84,6 +84,12 @@ nullPointer:common/utils/T/tracer/multi.c:265 arrayIndexOutOfBounds:openair2/LAYER2/rlc_v2/tests/test.c:401 // //----------------------------------------------------------------------------- +// this file is used for testing the NR RLC implementation, this error is +// not a problem, the programmer has to know what she does when writing +// the tests +arrayIndexOutOfBounds:openair2/LAYER2/nr_rlc/tests/test.c:451 +// +//----------------------------------------------------------------------------- // cppcheck does not understand the different lengths of arrays arrayIndexOutOfBounds:openair1/SIMULATION/TOOLS/random_channel.c:705 arrayIndexOutOfBounds:openair1/SIMULATION/TOOLS/random_channel.c:706 diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index 25bbbba091..a1994c5ac3 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -65,6 +65,7 @@ class EPCManagement(): self.testCase_id = '' self.MmeIPAddress = '' self.containerPrefix = 'prod' + self.mmeConfFile = 'mme.conf' #----------------------------------------------------------- @@ -127,7 +128,7 @@ class EPCManagement(): logging.debug('Using the OAI EPC Release 14 MME in Docker') mySSH.command('docker exec -d ' + self.containerPrefix + '-oai-mme /bin/bash -c "nohup tshark -i eth0 -i lo:s10 -w /tmp/mme_check_run.pcap 2>&1 > /dev/null"', '\$', 5) time.sleep(5) - mySSH.command('docker exec -d ' + self.containerPrefix + '-oai-mme /bin/bash -c "nohup ./bin/oai_mme -c ./etc/mme.conf > mme_check_run.log 2>&1"', '\$', 5) + mySSH.command('docker exec -d ' + self.containerPrefix + '-oai-mme /bin/bash -c "nohup ./bin/oai_mme -c ./etc/' + self.mmeConfFile + ' > mme_check_run.log 2>&1"', '\$', 5) elif re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE): logging.debug('Using the OAI EPC Release 14 MME') mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5) diff --git a/ci-scripts/html.py b/ci-scripts/html.py index 8f2d38cced..f50899be4f 100644 --- a/ci-scripts/html.py +++ b/ci-scripts/html.py @@ -64,6 +64,10 @@ class HTMLManagement(): self.htmlTabIcons = [] self.testXMLfiles = [] + self.testUnstable = False + self.testMinStableId = '999999' + self.testStabilityPointReached = False + self.htmleNBFailureMsg = '' self.htmlUEFailureMsg = '' @@ -230,13 +234,20 @@ class HTMLManagement(): def CreateHtmlTabFooter(self, passStatus): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): + testOkEvenIfUnstable = False + if self.testUnstable and not passStatus: + if self.testStabilityPointReached or self.testMinStableId == '999999': + testOkEvenIfUnstable = True self.htmlFile = open('test_results.html', 'a') self.htmlFile.write(' \n') self.htmlFile.write(' Final Tab Status\n') if passStatus: self.htmlFile.write(' PASS \n') else: - self.htmlFile.write(' FAIL \n') + if testOkEvenIfUnstable: + self.htmlFile.write(' KNOWN UNSTABLE SCENARIO \n') + else: + self.htmlFile.write(' FAIL \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') @@ -246,7 +257,10 @@ class HTMLManagement(): cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__//' test_results.html" subprocess.run(cmd, shell=True) else: - cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<\/span>/' test_results.html" + if testOkEvenIfUnstable: + cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<\/span>/' test_results.html" + else: + cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<\/span>/' test_results.html" subprocess.run(cmd, shell=True) self.htmlFooterCreated = False diff --git a/ci-scripts/main.py b/ci-scripts/main.py index ca29538713..8fbc3b93a0 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -283,6 +283,11 @@ def GetParametersFromXML(action): else: ldpc.forced_workspace_cleanup=False + elif action == 'Initialize_MME': + string_field = test.findtext('option') + if (string_field is not None): + EPC.mmeConfFile = string_field + else: # ie action == 'Run_PhySim': ldpc.runargs = test.findtext('physim_run_args') @@ -489,6 +494,9 @@ elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): CiTestObj.RetrieveSystemVersion('UE',HTML,RAN) HTML.CreateHtmlFooter(CiTestObj.finalStatus) elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE): + logging.debug('\u001B[1m----------------------------------------\u001B[0m') + logging.debug('\u001B[1m Starting Scenario \u001B[0m') + logging.debug('\u001B[1m----------------------------------------\u001B[0m') if re.match('^TesteNB$', mode, re.IGNORECASE): if RAN.eNBIPAddress == '' or RAN.ranRepository == '' or RAN.ranBranch == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '' or EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '': HELP.GenericHelp(CONST.Version) @@ -524,7 +532,14 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re HTML.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) HTML.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0')) repeatCount = xmlRoot.findtext('repeatCount',default='1') + testStability = xmlRoot.findtext('TestUnstable',default='False') CiTestObj.repeatCounts.append(int(repeatCount)) + if testStability == 'True': + CiTestObj.testUnstable = True + HTML.testUnstable = True + CiTestObj.testMinStableId = xmlRoot.findtext('TestMinId',default='999999') + HTML.testMinStableId = CiTestObj.testMinStableId + logging.debug('Test is tagged as Unstable -- starting from TestID ' + str(CiTestObj.testMinStableId)) all_tests=xmlRoot.findall('testCase') exclusion_tests=exclusion_tests.split() @@ -605,7 +620,11 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re if (CiTestObj.ADBIPAddress != 'none'): #in these cases, having no devices is critical, GetAllUEDevices function has to manage it as a critical error, reason why terminate_ue_flag is set to True terminate_ue_flag = True - CiTestObj.GetAllUEDevices(terminate_ue_flag) + # Now we stop properly the test-suite --> clean reporting + status = CiTestObj.GetAllUEDevices(terminate_ue_flag) + if not status: + RAN.prematureExit = True + break if action == 'Build_eNB': RAN.BuildeNB() elif action == 'WaitEndBuild_eNB': @@ -681,11 +700,19 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re HTML=ldpc.Run_PhySim(HTML,CONST,id) else: sys.exit('Invalid class (action) from xml') + if not RAN.prematureExit: + if CiTestObj.testCase_id == CiTestObj.testMinStableId: + logging.debug('Scenario has reached minimal stability point') + CiTestObj.testStabilityPointReached = True + HTML.testStabilityPointReached = True CiTestObj.FailReportCnt += 1 if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and RAN.prematureExit: logging.debug('Testsuite failed ' + str(CiTestObj.FailReportCnt) + ' time(s)') HTML.CreateHtmlTabFooter(False) - sys.exit('Failed Scenario') + if CiTestObj.testUnstable and (CiTestObj.testStabilityPointReached or CiTestObj.testMinStableId == '999999'): + logging.debug('Scenario has reached minimal stability point -- Not a Failure') + else: + sys.exit('Failed Scenario') else: logging.info('Testsuite passed after ' + str(CiTestObj.FailReportCnt) + ' time(s)') HTML.CreateHtmlTabFooter(True) diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index d5906e9567..6425d55c8f 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -133,7 +133,7 @@ class RANManagement(): self.air_interface[self.eNB_instance] = 'nr-softmodem' else: self.air_interface[self.eNB_instance] = 'lte-softmodem' - + # Worakround for some servers, we need to erase completely the workspace if self.Build_eNB_forced_workspace_cleanup: mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) @@ -427,7 +427,7 @@ class RANManagement(): # Launch eNB with the modified config file mySSH.command('source oaienv', '\$', 5) mySSH.command('cd cmake_targets', '\$', 5) - if self.air_interface == 'nr': + if self.air_interface[self.eNB_instance] == 'nr-softmodem': mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm rbconfig.raw; fi', '\$', 5) mySSH.command('if [ -e reconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm reconfig.raw; fi', '\$', 5) # NOTE: WE SHALL do a check if the executable is present (in case build went wrong) @@ -705,6 +705,11 @@ class RANManagement(): systemTime = '' maxPhyMemUsage = '' nbContextSwitches = '' + #NSA FR1 check + NSA_RAPROC_PUSCH_check = 0 + #dlsch and ulsch statistics (dictionary) + dlsch_ulsch_stats = {} + for line in enb_log_file.readlines(): # Runtime statistics result = re.search('Run time:' ,str(line)) @@ -855,12 +860,27 @@ class RANManagement(): result = re.search('MBMS USER-PLANE.*Requesting.*bytes from RLC', str(line)) if result is not None: mbmsRequestMsg += 1 + #FR1 NSA test : add new markers to make sure gNB is used + result = re.search('\[gNB [0-9]+\]\[RAPROC\] PUSCH with TC_RNTI [0-9a-fA-F]+ received correctly, adding UE MAC Context UE_id [0-9]+\/RNTI [0-9a-fA-F]+', str(line)) + if result is not None: + NSA_RAPROC_PUSCH_check = 1 + #dlsch and ulsch statistics + #keys below are the markers we are loooking for, loop over this keys list + #everytime these markers are found in the log file, the previous ones are overwritten in the dict + #eventually we record and print only the last occurence + keys = {'dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled'} + for k in keys: + result = re.search(k, line) + if result is not None: + #remove 1- all useless char before relevant info (ulsch or dlsch) 2- trailing char + dlsch_ulsch_stats[k]=re.sub(r'^.*\]\s+', r'' , line.rstrip()) enb_log_file.close() logging.debug(' File analysis completed') if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'): nodeB_prefix = 'e' else: nodeB_prefix = 'g' + if self.air_interface[self.eNB_instance] == 'nr-softmodem': if ulschReceiveOK > 0: statMsg = nodeB_prefix + 'NB showed ' + str(ulschReceiveOK) + ' "ULSCH received ok" message(s)' @@ -874,6 +894,23 @@ class RANManagement(): statMsg = nodeB_prefix + 'NB ran with TX Write thread enabled' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') htmleNBFailureMsg += statMsg + '\n' + #FR1 NSA test : add new markers to make sure gNB is used + if NSA_RAPROC_PUSCH_check: + statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : PASS ' + htmlMsg = statMsg+'\n' + else: + statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : FAIL ' + htmlMsg = statMsg+'\n' + logging.debug(statMsg) + htmleNBFailureMsg += htmlMsg + #ulsch and dlsch statistics + if len(dlsch_ulsch_stats)!=0: #check if dictionary is not empty + statMsg='' + for key in dlsch_ulsch_stats: #for each dictionary key + statMsg += dlsch_ulsch_stats[key] + '\n' + logging.debug(dlsch_ulsch_stats[key]) + htmleNBFailureMsg += statMsg + if uciStatMsgCount > 0: statMsg = nodeB_prefix + 'NB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 03cda20542..8562f4b2de 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -470,7 +470,7 @@ function report_test { then NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfully configured" $UE_LOG` else - NB_UE_TUNNEL_UP=`egrep -c "executing ifconfig oaitun_ue1" $UE_LOG` + NB_UE_TUNNEL_UP=`egrep -c "ip link set oaitun_ue1 up" $UE_LOG` fi if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 0 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] then @@ -768,55 +768,47 @@ function report_test { #RA test (--do-ra option) -# Currently disabled -# #build log files names -# RA_ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb_ra_test.log -# RA_UE_LOG=$ARCHIVES_LOC/ra_check_${TMODE}_${BW}prb_${CN_CONFIG}_ue_ra_test.log -# if [ -f $RA_ENB_LOG ] && [ -f $RA_UE_LOG ] -# then -# #get rid of full path -# NAME_ENB=`echo $RA_ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` -# NAME_UE=`echo $RA_UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` -# echo " " >> ./test_simulator_results.html -# echo " $NAME_ENB --- $NAME_UE" >> ./test_simulator_results.html -# echo " Check if RA proc succeeded" >> ./test_simulator_results.html -# -# #gNB RA check -# GNB_RECEIVED=`egrep -c "received correctly" $RA_ENB_LOG` -# GNB_CONNECTED=`egrep -c "now 5G connected" $RA_ENB_LOG` -# #UE RA check -# UE_RA_PROC_OK=`egrep -c "RA procedure succeeded" $RA_UE_LOG` -# -# -# if [ $GNB_RECEIVED -gt 0 ] && [ $GNB_CONNECTED -gt 0 ] && [ $UE_RA_PROC_OK -gt 0 ] -# then -# echo " OK" >> ./test_simulator_results.html -# else -# echo " KO" >> ./test_simulator_results.html -# fi -# -# echo "
" >> ./test_simulator_results.html
-#                    if [ $GNB_RECEIVED -gt 0 ]
-#                    then
-#                        echo "- gNB --> RA received" >> ./test_simulator_results.html
-#                    else
-#                        echo "- gNB RA NOT RECEIVED" >> ./test_simulator_results.html
-#                    fi
-#                    if [ $GNB_CONNECTED -gt 0 ]
-#                    then
-#                        echo "- gNB --> 5G connected" >> ./test_simulator_results.html
-#                    else
-#                        echo "- gNB NOT 5G CONNECTED" >> ./test_simulator_results.html
-#                    fi
-#                    if [ $UE_RA_PROC_OK -gt 0 ]
-#                    then
-#                        echo "- NR UE  --> RA procedure succeded" >> ./test_simulator_results.html
-#                    else
-#                        echo "- NR UE RA procedure failed" >> ./test_simulator_results.html
-#                    fi
-#                    echo "        
" >> ./test_simulator_results.html -# echo " " >> ./test_simulator_results.html -# fi + #build log files names + RA_ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb_ra_test.log + RA_UE_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_ue_ra_test.log + if [ -f $RA_ENB_LOG ] && [ -f $RA_UE_LOG ] + then + #get rid of full path + NAME_ENB=`echo $RA_ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` + NAME_UE=`echo $RA_UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + echo " $NAME_ENB --- $NAME_UE" >> ./test_simulator_results.html + echo " Check if RA proc succeeded" >> ./test_simulator_results.html + + #gNB RA check + GNB_RECEIVED=`egrep -c "\[RAPROC\] PUSCH with TC_RNTI (.+) received correctly" $RA_ENB_LOG` + #UE RA check + UE_RA_PROC_OK=`egrep -c "\[RAPROC\] RA procedure succeeded" $RA_UE_LOG` + + + if [ $GNB_RECEIVED -gt 0 ] && [ $UE_RA_PROC_OK -gt 0 ] + then + echo " OK" >> ./test_simulator_results.html + else + echo " KO" >> ./test_simulator_results.html + fi + + echo "
" >> ./test_simulator_results.html
+                    if [ $GNB_RECEIVED -gt 0 ]
+                    then
+                        echo "- gNB --> RA received" >> ./test_simulator_results.html
+                    else
+                        echo "- gNB RA NOT RECEIVED" >> ./test_simulator_results.html
+                    fi
+                    if [ $UE_RA_PROC_OK -gt 0 ]
+                    then
+                        echo "- NR UE  --> RA procedure succeded" >> ./test_simulator_results.html
+                    else
+                        echo "- NR UE RA procedure failed" >> ./test_simulator_results.html
+                    fi
+                    echo "        
" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + fi #SYNC test ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb.log diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 734001040c..6c87f5dac3 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -281,14 +281,35 @@ function check_ra_result { local LOC_GNB_LOG=$1 local LOC_UE_LOG=$2 - #gNB RA test - echo "Checking gNB Log for RA success" - egrep "received correctly" $1 - egrep "now 5G connected" $1 - - #UE RA test - echo 'Checking UE Log for RA success' - egrep "RA procedure succeeded" $2 + #if log files exist + if [ -f $LOC_GNB_LOG ] && [ -f $LOC_UE_LOG ] + then + + #gNB RA test + #console check + echo "Checking gNB Log for RA success" + egrep "\[RAPROC\] PUSCH with TC_RNTI (.+) received correctly" $1 + #script check + local GNB_COMPLETE=`egrep -c "\[RAPROC\] PUSCH with TC_RNTI (.+) received correctly" $1` + + #UE RA test + #console check + echo 'Checking UE Log for RA success' + egrep "\[RAPROC\] RA procedure succeeded" $2 + #script check + local UE_COMPLETE=`egrep -c "\[RAPROC\] RA procedure succeeded" $2` + + #generate status + if [ $GNB_COMPLETE -eq 0 ] || [ $UE_COMPLETE -eq 0 ] + then + RA_STATUS=-1 + echo "RA test FAILED, could not find the markers" + fi + #case where log files do not exist + else + echo "RA test log files not present" + RA_STATUS=-1 + fi } @@ -1199,6 +1220,8 @@ function start_rf_sim_gnb { echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 echo "echo \"source oaienv\"" >> $1 echo "source oaienv" >> $1 + echo "echo \"export RFSIMULATOR=server\"" >> $1 + echo "export RFSIMULATOR=server" >> $1 echo "cd ci-scripts/conf_files/" >> $1 echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1 #echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_ENB_VM_IP_ADDR#' -e 's#CI_UE_IP_ADDR#$LOC_UE_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1 @@ -1212,9 +1235,9 @@ function start_rf_sim_gnb { then if [ $LOC_RA_TEST -eq 0 ] #no RA test => use --phy-test option then - echo "echo \"RFSIMULATOR=server ./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim --phy-test\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim --phy-test\" > ./my-nr-softmodem-run.sh " >> $1 else #RA test => use --do-ra option - echo "echo \"RFSIMULATOR=server ./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --rfsim --do-ra\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --rfsim --do-ra\" > ./my-nr-softmodem-run.sh " >> $1 fi fi echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 @@ -1225,16 +1248,6 @@ function start_rf_sim_gnb { ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1 rm $1 - # For the moment, in RA test, no check and no copy of generated raw files - if [ $LOC_RA_TEST -eq 1 ] # RA test - then - sleep 30 - echo "echo \"free -m\"" > $1 - echo "free -m" >> $1 - ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1 - rm $1 - return 0 - fi local i="0" echo "egrep -c \"got sync\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 @@ -1258,7 +1271,9 @@ function start_rf_sim_gnb { GNB_SYNC=1 echo "RF-SIM gNB is sync'ed: waiting for UE(s) to connect" fi - if [ $LOC_S1_CONFIGURATION -eq 0 ] + + # check noS1 config only outside RA test (as it does not support noS1) + if [ $LOC_S1_CONFIGURATION -eq 0 ] && [ $LOC_RA_TEST -eq 0 ] then echo "ifconfig oaitun_enb1 | egrep -c \"inet addr\"" > $1 # Checking oaitun_enb1 interface has now an IP address @@ -1307,30 +1322,25 @@ function start_rf_sim_nr_ue { local LOC_RA_TEST=$8 # Copy the RAW files from the gNB run - # In RA test mode, they were not copied from gNB VM - if [ $LOC_RA_TEST -eq 0 ] #no RA test => use --phy-test option - then - scp -o StrictHostKeyChecking=no rbconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp - scp -o StrictHostKeyChecking=no reconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp - fi + scp -o StrictHostKeyChecking=no rbconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp + scp -o StrictHostKeyChecking=no reconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp echo "echo \"sudo apt-get --yes --quiet install daemon \"" > $1 echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "echo \"export RFSIMULATOR=${LOC_GNB_VM_IP_ADDR}\"" >> $1 + echo "export RFSIMULATOR=${LOC_GNB_VM_IP_ADDR}" >> $1 echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1 echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 - if [ $LOC_RA_TEST -eq 0 ] #no RA test => use --phy-test option - then - echo "sudo cp /home/ubuntu/tmp/r*config.raw /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 - echo "sudo chmod 666 /home/ubuntu/tmp/cmake_targets/ran_build/build/r*config.raw" >> $1 - fi + echo "sudo cp /home/ubuntu/tmp/r*config.raw /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + echo "sudo chmod 666 /home/ubuntu/tmp/cmake_targets/ran_build/build/r*config.raw" >> $1 echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 if [ $LOC_S1_CONFIGURATION -eq 0 ] then if [ $LOC_RA_TEST -eq 0 ] #no RA test => use --phy-test option then - echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/ --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/ --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1 else #RA test => use --do-ra option - echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --rfsim --do-ra --log_config.global_log_options level,nocolor\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"./nr-uesoftmodem --rfsim --do-ra --log_config.global_log_options level,nocolor --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/\" > ./my-nr-softmodem-run.sh " >> $1 fi fi echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 @@ -1341,14 +1351,6 @@ function start_rf_sim_nr_ue { ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1 rm $1 - # In case of RA test mode, no UE sync check for the moment. - # To be removed later? - if [ $LOC_RA_TEST -eq 1 ] # RA test - then - sleep 30 - NR_UE_SYNC=1 - return 0 - fi local i="0" echo "egrep -c \"Initial sync: pbch decoded sucessfully\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 while [ $i -lt 10 ] @@ -1372,11 +1374,13 @@ function start_rf_sim_nr_ue { else echo "RF-SIM NR-UE is sync'ed w/ gNB" fi - # Checking oaitun_ue1 interface has now an IP address - i="0" - echo "ifconfig oaitun_ue1 | egrep -c \"inet addr\"" > $1 - while [ $i -lt 10 ] - do + # Checking oaitun_ue1 interface has now an IP address (only outside RA test) + if [ $LOC_RA_TEST -eq 0 ] + then + i="0" + echo "ifconfig oaitun_ue1 | egrep -c \"inet addr\"" > $1 + while [ $i -lt 10 ] + do sleep 5 CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1` if [ $CONNECTED -eq 1 ] @@ -1385,21 +1389,20 @@ function start_rf_sim_nr_ue { else i=$[$i+1] fi - done - echo "echo \"free -m\"" > $1 - echo "free -m" >> $1 - ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1 - rm $1 - if [ $i -lt 50 ] - then + done + echo "echo \"free -m\"" > $1 + echo "free -m" >> $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1 + rm $1 + if [ $i -lt 50 ] + then NR_UE_SYNC=0 echo "RF-SIM NR-UE oaitun_ue1 is DOWN or NOT CONFIGURED" - else + else echo "RF-SIM NR-UE oaitun_ue1 is UP and CONFIGURED" - fi - sleep 10 - - + fi + sleep 10 + fi } @@ -2192,14 +2195,21 @@ function run_test_on_vm { PRB=106 FREQUENCY=3510 + if [ ! -d $ARCHIVES_LOC ] + then + mkdir --parents $ARCHIVES_LOC + fi + local try_cnt="0" NR_STATUS=0 ######### start of RA TEST loop - while [ $try_cnt -lt 1 ] + while [ $try_cnt -lt 5 ] #5 because it hardly succeed within CI do SYNC_STATUS=0 + RA_STATUS=0 + rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}*ra_test.log echo "############################################################" echo "${CN_CONFIG} : Starting the gNB" @@ -2241,75 +2251,32 @@ function run_test_on_vm { echo "############################################################" # Proper check to be done when RA test is working! - #check_ra_result $ARCHIVES_LOC/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/$CURRENT_NR_UE_LOG_FILE - - try_cnt=$[$try_cnt+1] - - ########### end RA test + check_ra_result $ARCHIVES_LOC/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/$CURRENT_NR_UE_LOG_FILE + if [ $RA_STATUS -ne 0 ] + then + echo "RA test NOT OK" + try_cnt=$[$try_cnt+1] + else + try_cnt=$[$try_cnt+10] + fi done - sleep 10 - try_cnt="0" + ########### end RA test + + sleep 30 + ######### start of PHY TEST loop + try_cnt="0" while [ $try_cnt -lt 4 ] do - #start RA test - SYNC_STATUS=0 - PING_STATUS=0 - IPERF_STATUS=0 - - echo "############################################################" - echo "${CN_CONFIG} : Starting the gNB" - echo "############################################################" - CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log - #last argument = 1 is to enable --do-ra for RA test - start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 1 - - echo "############################################################" - echo "${CN_CONFIG} : Starting the NR-UE" - echo "############################################################" - CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log - #last argument = 1 is to enable --do-ra for RA test - start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 1 - if [ $NR_UE_SYNC -eq 0 ] - then - echo "Problem w/ gNB and NR-UE not syncing" - terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2 - terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1 - scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC - SYNC_STATUS=-1 - try_cnt=$[$try_cnt+1] - continue - fi - - echo "############################################################" - echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators" - echo "############################################################" - sleep 20 - terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2 - terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1 - scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC - - #check RA markers in gNB and NR UE log files - echo "############################################################" - echo "${CN_CONFIG} : Checking RA on gNB / NR-UE" - echo "############################################################" - - mv $ARCHIVES_LOC/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/ra_check_$CURRENT_GNB_LOG_FILE - mv $ARCHIVES_LOC/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC/ra_check_$CURRENT_NR_UE_LOG_FILE - # Proper check to be done when RA test is working! - #check_ra_result $ARCHIVES_LOC/ra_check_$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/ra_check_$CURRENT_NR_UE_LOG_FILE - - - #end RA test - sleep 30 SYNC_STATUS=0 PING_STATUS=0 IPERF_STATUS=0 + rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_gnb.log $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ue.log + rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log + rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_iperf_dl*txt $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_iperf_ul*txt echo "############################################################" echo "${CN_CONFIG} : Starting the gNB" @@ -2409,6 +2376,7 @@ function run_test_on_vm { echo "Checking run status" echo "############################################################" + if [ $RA_STATUS -ne 0 ]; then NR_STATUS=-1; fi if [ $SYNC_STATUS -ne 0 ]; then NR_STATUS=-1; fi if [ $PING_STATUS -ne 0 ]; then NR_STATUS=-1; fi if [ $IPERF_STATUS -ne 0 ]; then NR_STATUS=-1; fi diff --git a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml index 611492b0bc..cdba0723df 100644 --- a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml @@ -25,6 +25,7 @@ Test-LTE-M-10MHz-TM1 tasks 1 + True 030201 040102 diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml index 09aa0b04a2..5ece10d37e 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml @@ -26,6 +26,8 @@ Test-05MHz-TM2 tasks 2 + True + 040608 030201 040101 diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml index 29699d3b3d..b1d87e598e 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml @@ -24,6 +24,8 @@ test-10-tm1 Test-10MHz-TM1 tasks + True + 040615 030201 040101 diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml index f98ed1600a..d75704aceb 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml @@ -25,6 +25,8 @@ Test-20MHz-TM1 tasks 4 + True + 040623 030201 040101 diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml index fd018f7a9c..a6530a920c 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml @@ -24,6 +24,8 @@ test-20-tm1-defSched Test-20MHz-TM1-default-scheduler tasks + True + 040522 030201 040101 diff --git a/ci-scripts/xml_files/fr1_epc_start_verizon.xml b/ci-scripts/xml_files/fr1_epc_start_verizon.xml new file mode 100644 index 0000000000..19f5c03985 --- /dev/null +++ b/ci-scripts/xml_files/fr1_epc_start_verizon.xml @@ -0,0 +1,49 @@ + + + epc-start-tab + EPC-Start + log-in + + 000100 000101 000102 + + + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/fr1_ran_ue_proc.xml b/ci-scripts/xml_files/fr1_ran_ue_proc.xml index e86a36d2db..330fb27f21 100644 --- a/ci-scripts/xml_files/fr1_ran_ue_proc.xml +++ b/ci-scripts/xml_files/fr1_ran_ue_proc.xml @@ -89,14 +89,14 @@ Ping Ping: 20pings in 20sec -c 20 - 0 + 50 Ping Ping: 5pings in 1sec -c 5 -i 0.2 - 0 + 50 @@ -104,6 +104,7 @@ Terminate eNB 0 0 + lte @@ -111,6 +112,7 @@ Terminate gNB 1 1 + nr diff --git a/ci-scripts/xml_files/fr1_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/fr1_usrp210_band7_test_05mhz_tm1.xml new file mode 100644 index 0000000000..ea25d5b694 --- /dev/null +++ b/ci-scripts/xml_files/fr1_usrp210_band7_test_05mhz_tm1.xml @@ -0,0 +1,151 @@ + + + test-05-tm1 + Test-05MHz-TM1 + tasks + + 030201 + 040101 + 030101 040301 000001 040501 040603 040401 030201 + + + + + IdleSleep + Sleep + 5 + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].plmn_list.[0].mcc 311 --eNBs.[0].plmn_list.[0].mnc 480 --eNBs.[0].plmn_list.[0].mnc_length 3 --eNBs.[0].component_carriers.[0].Nid_cell 10 + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) + -u -b 15M -t 30 -i 1 + 50 + balanced + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) + -u -b 15M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile) + -u -b 15M -t 30 -i 1 + 50 + unbalanced + + + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm + 50 + balanced + + + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) + -u -b 9M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) + -u -b 9M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm -R + 50 + balanced + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml index 8276294e9a..9224c67fe7 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml @@ -25,6 +25,8 @@ Test-10MHz tasks 2 + True + 040612 030201 040101 diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml index c43be75a87..7256c985c5 100644 --- a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml @@ -26,6 +26,7 @@ Test-X2-HO-FDD-05MHz-TM1 tasks 2 + True 030201 030202 040101 diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f530b60530..e034120781 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -23,6 +23,114 @@ cmake_minimum_required (VERSION 3.0) + +# System packages that are required +# We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ +# or cmake provide a generic interface to pkg-config that widely used +################################### +include(FindPkgConfig) + +pkg_search_module(LIBXML2 libxml-2.0 REQUIRED) +include_directories(${LIBXML2_INCLUDE_DIRS}) + +pkg_search_module(LIBXSLT libxslt REQUIRED) +include_directories(${LIBXSLT_INCLUDE_DIRS}) + +pkg_search_module(OPENSSL openssl REQUIRED) +include_directories(${OPENSSL_INCLUDE_DIRS}) + +pkg_search_module(CONFIG libconfig REQUIRED) +include_directories(${CONFIG_INCLUDE_DIRS}) + +pkg_search_module(CRYPTO libcrypto REQUIRED) +include_directories(${CRYPTO_INCLUDE_DIRS}) + +#use native cmake method as this package is not in pkg-config +if (${RF_BOARD} STREQUAL "OAI_USRP") + find_package(Boost REQUIRED) + include_directories(${LIBBOOST_INCLUDE_DIR}) + +elseif (${RF_BOARD} STREQUAL "OAI_IRIS") + include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/") + include_directories("/usr/local/include/") + set(HW_SOURCE ${HW_SOURCE} + ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp) + LINK_DIRECTORIES("/usr/local/lib") + set(option_HW_lib "-lSoapySDR -rdynamic -ldl") + +endif (${RF_BOARD} STREQUAL "OAI_USRP") + +pkg_search_module(OPENPGM openpgm-5.1 openpgm-5.2) +if(NOT ${OPENPGM_FOUND}) + message("PACKAGE openpgm-5.1 is required by binaries such as oaisim: will fail later if this target is built") +else() + include_directories(${OPENPGM_INCLUDE_DIRS}) +endif() + +pkg_search_module(NETTLE nettle) +if(NOT ${NETTLE_FOUND}) + message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!") +else() + include_directories(${NETTLE_INCLUDE_DIRS}) +endif() + +message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") + +string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) +string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) +message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") +message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") + +if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") + message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) +endif() + +add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") +add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") + +pkg_search_module(XPM xpm) +if(NOT ${XPM_FOUND}) + message("PACKAGE xpm not found: some targets will fail") +else() + include_directories(${XPM_INCLUDE_DIRS}) +endif() + +# Atlas is required by some packages, but not found in pkg-config +# So, here are some hacks here. Hope this gets fixed in future! +if(EXISTS "/usr/include/atlas/cblas.h" OR EXISTS "/usr/include/cblas.h") + include_directories("/usr/include/atlas") + LINK_DIRECTORIES("/usr/lib/lapack") + LINK_DIRECTORIES("/usr/lib64") + LINK_DIRECTORIES("/usr/lib64/atlas") #Added because atlas libraries in CentOS 7 are here! + + if(EXISTS "/usr/lib64/libblas.so" OR EXISTS "/usr/lib/libblas.so") #Case for CentOS7 + list(APPEND ATLAS_LIBRARIES blas) + + else() # Case for Ubuntu + list(APPEND ATLAS_LIBRARIES cblas) + endif() + + if(EXISTS "/usr/lib/atlas/libtatlas.so" OR EXISTS "/usr/lib64/atlas/libtatlas.so") #Case for CentOS7 + list(APPEND ATLAS_LIBRARIES tatlas) + else() + list(APPEND ATLAS_LIBRARIES atlas) #Case for Ubuntu + endif() + + list(APPEND ATLAS_LIBRARIES lapack) + +# for ubuntu 17.10, directories are different +elseif(EXISTS "/usr/include/x86_64-linux-gnu/cblas.h") + + include_directories("/usr/include/x86_64-linux-gnu") + LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu") + list(APPEND ATLAS_LIBRARIES cblas) + list(APPEND ATLAS_LIBRARIES atlas) + list(APPEND ATLAS_LIBRARIES lapack) + +else() + message("No Blas/Atlas libs found, some targets will fail") +endif() + ######################################################### # Base directories, compatible with legacy OAI building # ######################################################### @@ -232,8 +340,8 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU ######################### # set a flag for changes in the source code # these changes are related to hardcoded path to include .h files -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2") +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g3 -O0 -DMALLOC_CHECK_=3") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2 -fno-delete-null-pointer-checks") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O3") set(GIT_BRANCH "UNKNOWN") @@ -302,7 +410,6 @@ set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti) add_library(ITTI ${OCP_ITTI}/intertask_interface.cpp ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/memory_pools.c ) add_dependencies(ITTI rrc_flag) set(ITTI_LIB ITTI) @@ -378,6 +485,7 @@ add_custom_target ( add_library(NR_RRC_LIB ${nr_rrc_h} ${nr_rrc_source} ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1_msg.c + ${OPENAIR2_DIR}/RRC/NR/nr_ngap_gNB.c ) add_dependencies(NR_RRC_LIB nr_rrc_flag) include_directories ("${NR_RRC_FULL_DIR}") @@ -675,7 +783,7 @@ add_library(X2AP_ENB ${X2AP_DIR}/x2ap_ids.c ${X2AP_DIR}/x2ap_timers.c ) -add_dependencies(X2AP_ENB rrc_flag x2_flag) +add_dependencies(X2AP_ENB X2AP_LIB rrc_flag x2_flag) # F1AP @@ -866,7 +974,7 @@ Message("CPU_Affinity flag is ${CPU_AFFINITY}") add_boolean_option(NO_RRM True "DO WE HAVE A RADIO RESSOURCE MANAGER: NO") add_boolean_option(OAI_NW_DRIVER_TYPE_ETHERNET False "????") -add_boolean_option(DEADLINE_SCHEDULER True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14") +add_boolean_option(DEADLINE_SCHEDULER False "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14") add_boolean_option(CPU_AFFINITY False "Enable CPU Affinity of threads (only valid without deadline scheduler). It is enabled only with >2 CPUs") add_boolean_option(NAS_NETLINK False "useless ??? Must be True to compile nasmesh driver without rtai ????") add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????") @@ -889,9 +997,9 @@ add_boolean_option(ENB_MODE True "Swap the include directories between openair2 ########################## # SCHEDULING/REAL-TIME/PERF options ########################## -add_boolean_option(ENABLE_USE_CPU_EXECUTION_TIME True "Add data in vcd traces: disable it if perf issues") -add_boolean_option(ENABLE_VCD True "always true now, time measurements of proc calls and var displays") -add_boolean_option(ENABLE_VCD_FIFO True "time measurements of proc calls and var displays sent to FIFO (one more thread)") +add_boolean_option(ENABLE_USE_CPU_EXECUTION_TIME False "Add data in vcd traces: disable it if perf issues") +add_boolean_option(ENABLE_VCD False "always true now, time measurements of proc calls and var displays") +add_boolean_option(ENABLE_VCD_FIFO False "time measurements of proc calls and var displays sent to FIFO (one more thread)") add_boolean_option(LINUX False "used in weird memcpy() in pdcp.c ???") add_boolean_option(LINUX_LIST False "used only in lists.c: either use OAI implementation of lists or Linux one (should be True, but it is False") add_boolean_option(OPENAIR_LTE True "Seems legacy: keep it to true") @@ -1305,6 +1413,7 @@ set(SECU_OSA_SRC ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c ) add_library(SECU_OSA ${SECU_OSA_SRC}) +target_link_libraries(SECU_OSA ${NETTLE_LIBRARIES}) set(SECU_CN_SRC ${OPENAIR3_DIR}/SECU/kdf.c @@ -1318,6 +1427,8 @@ set(SECU_CN_SRC ) add_library(SECU_CN ${SECU_CN_SRC}) +target_link_libraries(SECU_CN ${NETTLE_LIBRARIES}) + # Physical Channel Procedures Scheduling ################################" set(SCHED_SRC @@ -1648,6 +1759,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c @@ -1682,6 +1794,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/sss_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/cic_filter_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c + ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -2102,6 +2215,11 @@ set (GTPV1U_SRC add_library(GTPV1U ${GTPV1U_SRC}) add_dependencies(GTPV1U rrc_flag) +#add_library (GTPV1U_OCP +#${OPENAIR3_DIR}/ocp-gtp/gtp_itf.cpp +#) +#include_directories(${OPENAIR3_DIR}/ocp-gtp) + #NR case set (NR_GTPV1U_SRC ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c @@ -2523,6 +2641,14 @@ set (SHLIB_LOADER_SOURCES ${OPENAIR_DIR}/common/utils/load_module_shlib.c ) +add_library(LIB_5GNAS_GNB + ${NAS_SRC}/COMMON/nr_common.c + ${NAS_SRC}/gNB/network_process_nas.c + ${NAS_SRC}/NR_UE/ue_process_nas.c + ${OPENAIR3_DIR}//UICC/usim_interface.c + ) +target_link_libraries(LIB_5GNAS_GNB SECU_CN ${CRYPTO_LIBRARIES}) + # Make lfds as a own source code (even if it is a outside library) # For better intergration with compilation flags & structure of cmake ################################################################### @@ -2599,114 +2725,6 @@ include_directories("${NFAPI_DIR}/nfapi/inc") include_directories("${NFAPI_DIR}/sim_common/inc") include_directories("${NFAPI_DIR}/pnf_sim/inc") - -# System packages that are required -# We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ -# or cmake provide a generic interface to pkg-config that widely used -################################### -include(FindPkgConfig) - -pkg_search_module(LIBXML2 libxml-2.0 REQUIRED) -include_directories(${LIBXML2_INCLUDE_DIRS}) - -pkg_search_module(LIBXSLT libxslt REQUIRED) -include_directories(${LIBXSLT_INCLUDE_DIRS}) - -pkg_search_module(OPENSSL openssl REQUIRED) -include_directories(${OPENSSL_INCLUDE_DIRS}) - -pkg_search_module(CONFIG libconfig REQUIRED) -include_directories(${CONFIG_INCLUDE_DIRS}) - -pkg_search_module(CRYPTO libcrypto REQUIRED) -include_directories(${CRYPTO_INCLUDE_DIRS}) - -#use native cmake method as this package is not in pkg-config -if (${RF_BOARD} STREQUAL "OAI_USRP") - find_package(Boost REQUIRED) - include_directories(${LIBBOOST_INCLUDE_DIR}) - -elseif (${RF_BOARD} STREQUAL "OAI_IRIS") - include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/") - include_directories("/usr/local/include/") - set(HW_SOURCE ${HW_SOURCE} - ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp) - LINK_DIRECTORIES("/usr/local/lib") - set(option_HW_lib "-lSoapySDR -rdynamic -ldl") - -endif (${RF_BOARD} STREQUAL "OAI_USRP") - -pkg_search_module(OPENPGM openpgm-5.1 openpgm-5.2) -if(NOT ${OPENPGM_FOUND}) - message("PACKAGE openpgm-5.1 is required by binaries such as oaisim: will fail later if this target is built") -else() - include_directories(${OPENPGM_INCLUDE_DIRS}) -endif() - -pkg_search_module(NETTLE nettle) -if(NOT ${NETTLE_FOUND}) - message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!") -else() - include_directories(${NETTLE_INCLUDE_DIRS}) -endif() - -message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") - -string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) -string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) -message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") -message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") - -if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") - message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -endif() - -add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") -add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") - -pkg_search_module(XPM xpm) -if(NOT ${XPM_FOUND}) - message("PACKAGE xpm not found: some targets will fail") -else() - include_directories(${XPM_INCLUDE_DIRS}) -endif() - -# Atlas is required by some packages, but not found in pkg-config -# So, here are some hacks here. Hope this gets fixed in future! -if(EXISTS "/usr/include/atlas/cblas.h" OR EXISTS "/usr/include/cblas.h") - include_directories("/usr/include/atlas") - LINK_DIRECTORIES("/usr/lib/lapack") - LINK_DIRECTORIES("/usr/lib64") - LINK_DIRECTORIES("/usr/lib64/atlas") #Added because atlas libraries in CentOS 7 are here! - - if(EXISTS "/usr/lib64/libblas.so" OR EXISTS "/usr/lib/libblas.so") #Case for CentOS7 - list(APPEND ATLAS_LIBRARIES blas) - - else() # Case for Ubuntu - list(APPEND ATLAS_LIBRARIES cblas) - endif() - - if(EXISTS "/usr/lib/atlas/libtatlas.so" OR EXISTS "/usr/lib64/atlas/libtatlas.so") #Case for CentOS7 - list(APPEND ATLAS_LIBRARIES tatlas) - else() - list(APPEND ATLAS_LIBRARIES atlas) #Case for Ubuntu - endif() - - list(APPEND ATLAS_LIBRARIES lapack) - -# for ubuntu 17.10, directories are different -elseif(EXISTS "/usr/include/x86_64-linux-gnu/cblas.h") - - include_directories("/usr/include/x86_64-linux-gnu") - LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu") - list(APPEND ATLAS_LIBRARIES cblas) - list(APPEND ATLAS_LIBRARIES atlas) - list(APPEND ATLAS_LIBRARIES lapack) - -else() - message("No Blas/Atlas libs found, some targets will fail") -endif() - list(APPEND ATLAS_LIBRARIES lapack lapacke) include_directories ("/usr/include/X11") @@ -2813,6 +2831,12 @@ add_executable(measurement_display ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c) target_link_libraries (measurement_display minimal_lib) +add_executable(test5Gnas + ${OPENAIR_DIR}/openair3/TEST/test5Gnas.c +) +target_link_libraries (test5Gnas LIB_5GNAS_GNB CONFIG_LIB minimal_lib ) + + # lte-softmodem is both eNB and UE implementation ################################################### @@ -2854,7 +2878,7 @@ target_link_libraries (lte-softmodem -Wl,--end-group z dl) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem ${T_LIB}) @@ -2893,7 +2917,7 @@ target_link_libraries (ocp-enb PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) -target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB}) +target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB}) add_executable(cu_test ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/cu_test.c @@ -2965,7 +2989,7 @@ target_link_libraries (lte-uesoftmodem -Wl,--end-group z dl) target_link_libraries (lte-uesoftmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (lte-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-uesoftmodem ${T_LIB}) @@ -3008,11 +3032,52 @@ target_link_libraries (nr-softmodem -Wl,--end-group z dl) target_link_libraries (nr-softmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${T_LIB}) add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) + +add_executable(ocp-gnb + ${rrc_h} + ${nr_rrc_h} + ${s1ap_h} +# ${OPENAIR_BIN_DIR}/messages_xml.h + ${OPENAIR_DIR}/executables/ocp-gnb.c + ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c + ${OPENAIR_DIR}/executables/softmodem-common.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/RRC/NAS/rb_config.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/system.c + ${GTPU_need_ITTI} + ${XFORMS_SOURCE_NR} + ${T_SOURCE} + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} + ${XFORMSINTERFACE_SOURCE} + ) + +target_link_libraries (ocp-gnb + -Wl,--start-group + UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA + ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB + S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB + X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB SIMU_COMMON + -Wl,--end-group z dl) + +target_link_libraries (ocp-gnb ${LIBXML2_LIBRARIES} ) +target_link_libraries (ocp-gnb pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (ocp-gnb ${LIB_LMS_LIBRARIES}) +target_link_libraries (ocp-gnb ${T_LIB}) +add_dependencies(ocp-gnb ldpc_orig ldpc_optim ldpc_optim8seg ldpc params_libconfig rfsimulator oai_usrpdevif rfsimulator nrscope) + + # nr-uesoftmodem is UE implementation ####################################### @@ -3047,11 +3112,11 @@ target_link_libraries (nr-uesoftmodem RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB S1AP_LIB S1AP_ENB - ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} LIB_5GNAS_GNB -Wl,--end-group z dl) target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${T_LIB}) @@ -3218,7 +3283,7 @@ add_executable(nr_dlsim ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_dlsim - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR HASHTABLE -Wl,--end-group + -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl ) target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR) @@ -3236,7 +3301,8 @@ add_executable(nr_prachsim ${T_SOURCE} ${SHLIB_LOADER_SOURCES}) target_link_libraries(nr_prachsim - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB MAC_UE_NR SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB HASHTABLE -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c @@ -3268,7 +3334,7 @@ add_executable(nr_ulsim ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_ulsim - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR HASHTABLE -Wl,--end-group + -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl ) target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR) @@ -3303,7 +3369,7 @@ add_executable(test_epc_generate_scenario ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h ) target_link_libraries (test_epc_generate_scenario - -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) add_executable(test_epc_play_scenario @@ -3322,7 +3388,7 @@ add_executable(test_epc_play_scenario ) target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_link_libraries (test_epc_play_scenario - -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) @@ -3342,7 +3408,7 @@ foreach(myExe s1ap ${OPENAIR3_DIR}/TEST/test_${myExe}.c ) target_link_libraries (test_${myExe} - -Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) endforeach(myExe) @@ -3367,7 +3433,7 @@ if (${T_TRACER}) SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX - L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR + L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U NR_GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts) if (TARGET ${i}) @@ -3479,7 +3545,7 @@ target_link_libraries (nr-ittisim ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} - NR_L2_UE + PHY_NR_UE SCHED_NR_UE_LIB NR_L2_UE -Wl,--end-group z dl) target_link_libraries (nr-ittisim ${LIBXML2_LIBRARIES}) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 61d38ebed8..960b241047 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -42,7 +42,6 @@ MSC_GEN=0 XFORMS="True" SKIP_SHARED_LIB_FLAG="False" UE_EXPANSION="False" -UESIM_EXPANSION="False" PRINT_STATS="False" VCD_TIMING="False" DEADLINE_SCHEDULER_FLAG_USER="" @@ -267,10 +266,6 @@ function main() { UE_EXPANSION="True" echo_info "Will compile with UE_EXPANSION" shift;; - --musim) - UESIM_EXPANSION="True" - echo_info "Will compile with UESIM_EXPANSION" - shift;; --UE-conf-nvram) conf_nvram_path=$(readlink -f $2) shift 2;; @@ -496,11 +491,6 @@ function main() { echo_info "Flags for Deadline scheduler: $DEADLINE_SCHEDULER_FLAG_USER" echo_info "Flags for CPU Affinity: $CPU_AFFINITY_FLAG_USER" - if [ -n "$UHD_IMAGES_DIR" ] && [ -z "$INSTALL_EXTERNAL" ]; then - echo_error "UHD images download settings will not be applied without -I present" - exit - fi - ####################################################### # Setting and printing OAI envs, we should check here # ####################################################### @@ -601,7 +591,6 @@ function main() { echo "set ( UE_EXPANSION $UE_EXPANSION )" >> $cmake_file # echo "set ( PHY_TX_THREAD $UE_EXPANSION )" >> $cmake_file echo "set ( PRE_SCD_THREAD $UE_EXPANSION )" >> $cmake_file - echo "set ( UESIM_EXPANSION $UESIM_EXPANSION )" >> $cmake_file echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file echo "set ( TRANSP_PRO \"${TP}\")" >> $cmake_file diff --git a/cmake_targets/install_external_packages.ubuntu20 b/cmake_targets/install_external_packages.ubuntu20 new file mode 100755 index 0000000000..9ef79be9c2 --- /dev/null +++ b/cmake_targets/install_external_packages.ubuntu20 @@ -0,0 +1,505 @@ +#!/bin/bash +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ + +# brief +# authors Laurent Thomas +# +####################################### +if [ ! -f /etc/os-release ]; then + echo "No /etc/os-release file found. You're likely on an unsupported distro." + exit 1 +fi +OS_DISTRO=$(grep "^ID=" /etc/os-release | sed "s/ID=//" | sed "s/\"//g") +OS_RELEASE=$(grep "^VERSION_ID=" /etc/os-release | sed "s/VERSION_ID=//" | sed "s/\"//g") +case "$OS_DISTRO" in + ubuntu) OS_BASEDISTRO="debian"; INSTALLER="apt"; CMAKE="cmake" ;; +esac + +SUDO='sudo -E' + +############################### +## echo and family +############################### +black='\E[30m' +red='\E[31m' +green='\E[32m' +yellow='\E[33m' +blue='\E[1;34m' +magenta='\E[35m' +cyan='\E[36m' +white='\E[37m' +reset_color='\E[00m' +COLORIZE=1 + +cecho() { + # Color-echo + # arg1 = message + # arg2 = color + local default_msg="No Message." + message=${1:-$default_msg} + color=${2:-$green} + [ "$COLORIZE" = "1" ] && message="$color$message$reset_color" + echo -e "$message" + return +} + +echo_error() { cecho "$* $red" ;} +echo_fatal() { cecho "$* $red"; exit 1 ;} +echo_warning() { cecho "$* $yellow" ;} +echo_success() { cecho "$* $green" ;} +echo_info() { cecho "$* $blue" ;} + +######################## +# distribution helpers # +######################## + +# This function return a string to identify the distribution we are running +# Examples: +# ubuntu16.04 +# debian8.5 +get_distribution_release() { + echo "$OS_DISTRO$OS_RELEASE" +} + +check_supported_distribution() { + case $(get_distribution_release) in + "ubuntu20.04") return 0 ;; + esac + return 1 +} + +################## +# Error handlers # +################## + +handler_EXIT() { + local exit_code=$? + [ "$exit_code" -eq 0 ] || echo_error "build have failed" + exit $exit_code +} + +trap handler_EXIT EXIT + +########################### +# Cleaners +########################### + +clean_kernel() { + $SUDO modprobe ip_tables + $SUDO modprobe x_tables + $SUDO iptables -P INPUT ACCEPT + $SUDO iptables -F INPUT + $SUDO iptables -P OUTPUT ACCEPT + $SUDO iptables -F OUTPUT + $SUDO iptables -P FORWARD ACCEPT + $SUDO iptables -F FORWARD + $SUDO iptables -t nat -F + $SUDO iptables -t mangle -F + $SUDO iptables -t filter -F + $SUDO iptables -t raw -F + echo_info "Flushed iptables" + $SUDO rmmod nasmesh > /dev/null 2>&1 + $SUDO rmmod oai_nw_drv > /dev/null 2>&1 + $SUDO rmmod openair_rf > /dev/null 2>&1 + $SUDO rmmod ue_ip > /dev/null 2>&1 + echo_info "removed drivers from kernel" +} + +clean_all_files() { + set_openair_env + rm -rf "$OPENAIR_DIR"/targets/bin/* + dir="$OPENAIR_DIR/cmake_targets" + rm -rf "$dir"/log/* + rm -rf "$dir"/ran_build/build + rm -rf "$dir"/ran_build_noLOG/build + rm -rf "$dir"/lte-simulators/build + rm -rf "$dir"/phy_simulators/build + rm -rf "$dir"/nas_sim_tools/build + rm -rf "$dir"/oaisim_build_oai/build + rm -rf "$dir"/oaisim_build_oai/CMakeLists.txt + rm -rf "$dir"/autotests/bin + rm -rf "$dir"/autotests/log + rm -rf "$dir"/autotests/*/build +} + +############################################ +# External packages installers +############################################ + +install_protobuf_from_source(){ + protobuf_install_log=$OPENAIR_DIR/cmake_targets/log/protobuf_install_log.txt + echo_info "\nInstalling Google Protobuf from sources. The log file for Protobuf installation is here: $protobuf_install_log " + ( + cd /tmp || exit + echo "Downloading protobuf" + #rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1 + #wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz + #tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner + #cd protobuf-2.6.1/ + rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0 + wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz + tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner "$USER" --group "$(groups | cut -d" " -f1)" --no-same-owner + cd protobuf-3.3.0/ || exit + ./configure + echo "Compiling protobuf" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + ) >& "$protobuf_install_log" +} + +install_protobuf_c_from_source(){ + protobuf_c_install_log=$OPENAIR_DIR/cmake_targets/log/protobuf_c_install_log.txt + echo_info "\nInstalling Google Protobuf_C from sources. The log file for Protobuf_C installation is here: $protobuf_c_install_log " + ( + if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then + export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig + fi + cd /tmp || exit + echo "Downloading protobuf-c" + rm -rf /tmp/protobuf-c + git clone https://github.com/protobuf-c/protobuf-c.git + cd protobuf-c || exit + git checkout 2a46af42784abf86804d536f6e0122d47cfeea45 + ./autogen.sh + ./configure + echo "Compiling protobuf-c" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + ) >& "$protobuf_c_install_log" +} + +install_usrp_uhd_driver_from_source(){ + uhd_install_log=$OPENAIR_DIR/cmake_targets/log/uhd_install_log.txt + echo_info "\nInstalling UHD driver from sources. The log file for UHD driver installation is here: $uhd_install_log " + ( + cd /tmp || exit + echo "Downloading UHD driver" + rm -rf /tmp/uhd + git clone https://github.com/EttusResearch/uhd.git + cd uhd || exit + git checkout tags/v3.13.0.2 + mkdir -p host/build + cd host/build || exit + $CMAKE ../ + echo "Compiling UHD" + make -j"$(nproc)" + make test + $SUDO make install + $SUDO ldconfig + ) >& "$uhd_install_log" +} + +install_bladerf_driver_from_source(){ + bladerf_install_log=$OPENAIR_DIR/cmake_targets/log/bladerf_install_log.txt + echo_info "\nInstalling BladeRF driver from sources. The log file for BladeRF driver installation is here: $bladerf_install_log " + ( + cd /tmp || exit + echo "Downloading BladeRF driver" + rm -rf /tmp/bladeRF + git clone https://github.com/Nuand/bladeRF.git + cd bladeRF || exit + git checkout tags/2016.06 + mkdir -p build + cd build || exit + $CMAKE ../ + echo "Compiling BladeRF driver" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + echo "Downloading FPGA and firmware images" + cd /tmp/bladeRF || exit + wget --tries=3 --retry-connrefused https://www.nuand.com/fx3/bladeRF_fw_latest.img + wget --tries=3 --retry-connrefused https://www.nuand.com/fpga/hostedx40-latest.rbf + sudo mkdir -p /usr/share/Nuand/bladeRF + sudo mv bladeRF_fw_latest.img /usr/share/Nuand/bladeRF/bladeRF_fw.img + sudo mv hostedx40-latest.rbf /usr/share/Nuand/bladeRF/hostedx40.rbf + ) >& "$bladerf_install_log" +} + +check_install_bladerf_driver(){ + if [[ "$OS_DISTRO" == "ubuntu" ]]; then + $SUDO apt-get install -y bladerf libbladerf-dev + $SUDO apt-get install -y bladerf-firmware-fx3 + $SUDO apt-get install -y bladerf-fpga-hostedx40 + elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then + install_bladerf_driver_from_source + else + echo_error "BladeRF Installer for OAI does not support automatic build. Install BladeRF compiling sources manually from BladeRF website" + fi +} + +flash_firmware_bladerf() { + $SUDO bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img +} + +install_soapy_from_source(){ + soapy_install_log=$OPENAIR_DIR/cmake_targets/log/soapy_install_log.txt + echo_info "\nInstalling Soapy EcoSystem from source. The log file for Soapy installation is here: $soapy_install_log " + ( + cd /tmp || exit + echo "Downloading SoapySDR" + rm -rf /tmp/soapysdr + git clone -b soapy-sdr-0.7.0 --single-branch https://github.com/pothosware/SoapySDR.git + cd SoapySDR || exit + #git checkout tags/release_003_010_001_001 + mkdir -p build + cd build || exit + $CMAKE ../ + echo "Compiling SoapySDR" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + cd /tmp || exit + echo "Downloading SoapyRemote" + rm -rf /tmp/soapyremote + git clone -b soapy-remote-0.5.0 --single-branch https://github.com/pothosware/SoapyRemote.git + cd SoapyRemote || exit + #git checkout tags/release_003_010_001_001 + mkdir -p build + cd build || exit + cmake ../ + echo "Compiling SoapyRemote" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + ) >& "$soapy_install_log" +} + +install_soapy_iris_from_source(){ + iris_install_log=$OPENAIR_DIR/cmake_targets/log/iris_install_log.txt + echo_info "\nInstalling Iris driver from source. The log file for Iris driver installation is here: $iris_install_log " + ( + cd /tmp || exit + echo "Downloading SoapyIris" + rm -rf /tmp/sklk-soapyiris + git clone -b soapy-iris-2018.08.0.1 --single-branch https://github.com/skylarkwireless/sklk-soapyiris.git + cd sklk-soapyiris || exit + mkdir -p build + cd build ||exit + cmake ../ + echo "Compiling SoapyIris" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + ) >& "$iris_install_log" +} + +check_install_soapy () { + #if [[ "$OS_DISTRO" == "ubuntu" ]]; then + #first we remove old installation + $SUDO apt-get remove -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote || true + #$SUDO add-apt-repository -y ppa:myriadrf/drivers + #$SUDO apt-get update + #$SUDO apt-get install -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote + + #elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then + # $SUDO $INSTALLER -y install software-properties-common python3-software-properties python-software-properties subversion git python3 python-numpy python3-numpy cmake swig python-dev + install_soapy_from_source + #fi + install_soapy_iris_from_source + +} + +check_install_ubuntu_packages() { + $SUDO $INSTALLER update -y + if [[ "$OS_DISTRO" == "ubuntu" ]]; then + local LAPACK_LIBNAME="liblapack.so" + local LAPACK_TARGET="/usr/lib/atlas-base/atlas/liblapack.so" + $SUDO apt install -y software-properties-common + case "$(get_distribution_release)" in + "ubuntu20.04") + specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev" + LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" + LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" + ;; + esac + $SUDO $INSTALLER install -y \ + $specific_packages \ + check \ + dialog \ + dkms \ + gawk \ + libboost-all-dev \ + libpthread-stubs0-dev \ + openvpn \ + pkg-config \ + python3-dev \ + python-pexpect \ + sshfs \ + swig \ + tshark \ + uml-utilities \ + unzip \ + valgrind \ + vlan \ + exuberant-ctags \ + ntpdate \ + iperf3 \ + android-tools-adb \ + wvdial \ + python-numpy \ + sshpass \ + nscd \ + bc \ + ntp \ + python3-scipy \ + python3-matplotlib \ + bison \ + build-essential \ + cmake \ + cmake-curses-gui \ + ninja-build \ + doxygen \ + doxygen-gui \ + texlive-latex-base \ + ethtool \ + flex \ + gdb \ + git \ + graphviz \ + gtkwave \ + guile-2.0-dev \ + iperf \ + iptables \ + libxtables-dev \ + libatlas-base-dev \ + libblas-dev \ + liblapack-dev\ + liblapacke-dev\ + libffi-dev \ + libforms-bin \ + libforms-dev \ + libgcrypt20-dev \ + libgmp-dev \ + libgtk-3-dev \ + libidn2-0-dev \ + libidn11-dev \ + libmysqlclient-dev \ + libpython2.7-dev \ + libsctp1 \ + libsctp-dev \ + libssl-dev \ + libtool \ + libusb-1.0-0-dev \ + libxml2 \ + libxml2-dev \ + libxslt1-dev \ + mscgen \ + octave-signal \ + openssh-client \ + openssh-server \ + openssl \ + python3 \ + subversion \ + xmlstarlet \ + python3-pip \ + libyaml-dev \ + wget \ + libxpm-dev \ + libboost-all-dev \ + nettle-dev \ + nettle-bin + fi + + $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET" + +} + +install_asn1c_from_source(){ + asn1_install_log=$OPENAIR_DIR/cmake_targets/log/asn1c_install_log.txt + echo_info "\nInstalling ASN1. The log file for ASN1 installation is here: $asn1_install_log " + ( + $SUDO rm -rf /tmp/asn1c + # GIT_SSL_NO_VERIFY=true git clone https://gitlab.eurecom.fr/oai/asn1c.git /tmp/asn1c + git clone https://gitlab.eurecom.fr/oai/asn1c.git /tmp/asn1c + cd /tmp/asn1c || exit + # better to use a given commit than a branch in case the branch + # is updated and requires modifications in the source of OAI + #git checkout velichkov_s1ap_plus_option_group + git checkout f12568d617dbf48497588f8e227d70388fa217c9 + autoreconf -iv + ./configure + make -j"$(nproc)" + $SUDO make install + cd - || exit + $SUDO ldconfig + ) > "$asn1_install_log" 2>&1 +} + +################################################# +# 2. compile +################################################ + +install_nas_tools() { + echo_success "generate .ue_emm.nvram .ue.nvram" + ./nvram --gen -c "$1" -o "$2" + ./usim --gen -c "$1" -o "$2" +} + + +################################ +# set_openair_env +############################### +set_openair_env(){ + fullpath=$(readlink -f "${BASH_SOURCE[0]}") + [ -f "/.$fullpath" ] || fullpath=$(readlink -f "$PWD/$fullpath") + openair_path=${fullpath%/cmake_targets/*} + openair_path=${openair_path%/targets/*} + openair_path=${openair_path%/openair[123]/*} + export OPENAIR_DIR=$openair_path + export OPENAIR1_DIR=$openair_path/openair1 + export OPENAIR2_DIR=$openair_path/openair2 + export OPENAIR3_DIR=$openair_path/openair3 + export OPENAIR_TARGETS=$openair_path/targets +} + +if ! check_supported_distribution; then + echo_error "Your distribution $(get_distribution_release) is not supported by oai !" + exit 1 +fi + +echo_info "Installing packages" +check_install_ubuntu_packages + +echo_info "installing ASN.1 compiler" +install_asn1c_from_source + +echo_info "installing protobuf/protobuf-c for flexran agent support" +install_protobuf_from_source +install_protobuf_c_from_source + +if [ "$1" == "USRP" ] ; then + echo_info "installing packages for USRP support" + install_usrp_uhd_driver +fi +if [ "$1" == "BLADERF" ] ; then + echo_info "installing packages for BLADERF support" + check_install_bladerf_driver + flash_firmware_bladerf +fi +if [ "$1" == "IRIS" ] ; then + echo_info "installing packages for IRIS support" + check_install_soapy + # flash_firmware_iris +fi diff --git a/cmake_targets/phy_simulators/CMakeLists.txt b/cmake_targets/phy_simulators/CMakeLists.txt index 00d46f9990..447e90bcab 100644 --- a/cmake_targets/phy_simulators/CMakeLists.txt +++ b/cmake_targets/phy_simulators/CMakeLists.txt @@ -4,7 +4,6 @@ set ( CMAKE_BUILD_TYPE ) set ( CFLAGS_PROCESSOR_USER "" ) set ( UE_EXPANSION False ) set ( PRE_SCD_THREAD False ) -set ( UESIM_EXPANSION False ) set ( ENABLE_VCD_FIFO False ) set ( RF_BOARD "None") set ( TRANSP_PRO "None") diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 7c50bc106a..f76eae7f28 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -42,12 +42,12 @@ KERNEL_MAJOR=$(uname -r | cut -d '.' -f2) #check if we run inside a container IS_CONTAINER=`egrep -c "docker|podman|kubepods" /proc/self/cgroup || true` -#sudo is not needed inside a container -if [ $IS_CONTAINER -eq 0 ] +#sudo is not needed when we are root +if [ "$UID" = 0 ] then - SUDO='sudo -S -E' -else SUDO='' +else + SUDO='sudo -S -E' fi ############################### @@ -251,18 +251,13 @@ install_protobuf_from_source(){ #wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz #tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner #cd protobuf-2.6.1/ - + if [ $IS_CONTAINER -eq 0 ] then rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0 wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz - tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $(groups | cut -d" " -f1) --no-same-owner + tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $(id -u) --group $(id -g) --no-same-owner cd protobuf-3.3.0/ - ./configure - echo "Compiling protobuf" - make -j`nproc` - $SUDO make install - $SUDO ldconfig else export LD_LIBRARY_PATH=/usr/local/lib #protoc needs to know where toclook for shared libs rm -rf /tmp/protobuf @@ -270,11 +265,12 @@ install_protobuf_from_source(){ cd /tmp/protobuf git submodule update --init --recursive ./autogen.sh - ./configure - make -j`nproc` - make install - ldconfig fi + ./configure + echo "Compiling protobuf" + make -j`nproc` + $SUDO make install + $SUDO ldconfig ) >& $protobuf_install_log } diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index ae2bf02f11..55dea68896 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -398,18 +398,21 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int /* define variable only used in LOG macro's */ # define LOG_VAR(A,B) A B # else /* T_TRACER: remove all debugging and tracing messages, except errors */ -# define LOG_I(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0)/* */ -# define LOG_W(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ; } while(0)/* */ -# define LOG_E(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ; } while(0)/* */ -# define LOG_D(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ; } while(0)/* */ -# define LOG_T(c, x...) /* */ -# define LOG_DUMPMSG(c, b, s, x...) /* */ +# define LOG_E(c, x...) do { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} while (0) +# define LOG_W(c, x...) do { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} while (0) +# define LOG_I(c, x...) do { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} while (0) +# define LOG_D(c, x...) do { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} while (0) +# define LOG_T(c, x...) do { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} while (0) +# define VLOG(c,l, f, args) do { if( g_log->log_component[c].level >= l ) vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, l, f, args) ; } while (0) + # define nfapi_log(FILE, FNC, LN, COMP, LVL, FMT...) -# define LOG_DEBUGFLAG(D) ( 0 ) -# define LOG_DUMPFLAG(D) ( 0 ) +# define LOG_DEBUGFLAG(D) (g_log->dump_mask & D) +# define LOG_DUMPFLAG(D) (g_log->debug_mask & D) +# define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */ + # define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0) -# define LOG_VAR(A,B) +# define LOG_VAR(A,B) A B # endif /* T_TRACER */ /* avoid warnings for variables only used in LOG macro's but set outside debug section */ #define GCC_NOTUSED __attribute__((unused)) diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 90857d7cd9..bd598b48da 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -814,6 +814,7 @@ static inline unsigned long long int vcd_get_time(void) return (long long unsigned int)((time.tv_nsec - g_time_start.tv_nsec)) + ((long long unsigned int)time.tv_sec - (long long unsigned int)g_time_start.tv_sec) * 1000000000UL; #endif + return 0; } void vcd_signal_dumper_create_header(void) diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index 601465c628..f9f5868260 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -601,11 +601,19 @@ extern int ouput_vcd; #else /* T_TRACER */ +#if ENABLE_VCD #define VCD_SIGNAL_DUMPER_INIT(aRgUmEnT) vcd_signal_dumper_init(aRgUmEnT) #define VCD_SIGNAL_DUMPER_CLOSE() vcd_signal_dumper_close() #define VCD_SIGNAL_DUMPER_CREATE_HEADER() vcd_signal_dumper_create_header() #define VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(vAr1,vAr2) vcd_signal_dumper_dump_variable_by_name(vAr1,vAr2) #define VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(vAr1,vAr2) vcd_signal_dumper_dump_function_by_name(vAr1,vAr2) +#else +#define VCD_SIGNAL_DUMPER_INIT(aRgUmEnT) +#define VCD_SIGNAL_DUMPER_CLOSE() +#define VCD_SIGNAL_DUMPER_CREATE_HEADER() +#define VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(vAr1,vAr2) +#define VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(vAr1,vAr2) +#endif #endif /* T_TRACER */ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 93e34d6a87..84fcdd55af 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -85,6 +85,10 @@ ID = ENB_PHY_MIB DESC = MIB data GROUP = ALL:PHY:ENB:WIRESHARK FORMAT = int,eNB_ID : int,frame : int,subframe : buffer,data +ID = GNB_PHY_MIB + DESC = NR MIB data + GROUP = ALL:PHY:GNB:WIRESHARK + FORMAT = int,gNB_ID : int,frame : int,slot : buffer,data #MAC logs ID = ENB_MAC_UE_DL_SDU @@ -131,6 +135,18 @@ ID = ENB_MAC_UE_DL_RAR_PDU_WITH_DATA DESC = MAC downlink PDU for an UE GROUP = ALL:MAC:ENB:WIRESHARK FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : buffer,data +ID = GNB_MAC_DL_PDU_WITH_DATA + DESC = NR MAC downlink PDU for an UE + GROUP = ALL:MAC:GNB:WIRESHARK + FORMAT = int,gNB_ID : int,CC_id : int,rnti : int,frame : int,slot : int,harq_pid : buffer,data +ID = GNB_MAC_UL_PDU_WITH_DATA + DESC = NR MAC uplink PDU for an UE + GROUP = ALL:MAC:GNB:WIRESHARK + FORMAT = int,gNB_ID : int,CC_id : int,rnti : int,frame : int,slot : int,harq_pid : buffer,data +ID = GNB_MAC_DL_RAR_PDU_WITH_DATA + DESC = NR MAC downlink PDU for RAR + GROUP = ALL:MAC:GNB:WIRESHARK + FORMAT = int,gNB_ID : int,CC_id : int,rnti : int,frame : int,slot : int,harq_pid : buffer,data #RLC logs ID = ENB_RLC_DL diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c index c391a99786..d262f09e4a 100644 --- a/common/utils/T/tracer/macpdu2wireshark.c +++ b/common/utils/T/tracer/macpdu2wireshark.c @@ -23,6 +23,8 @@ typedef struct { int socket; struct sockaddr_in to; OBUF buf; + + /* LTE traces */ /* ul */ int ul_rnti; int ul_frame; @@ -46,6 +48,28 @@ typedef struct { int rar_frame; int rar_subframe; int rar_data; + + /* NR traces */ + /* NR ul */ + int nr_ul_rnti; + int nr_ul_frame; + int nr_ul_slot; + int nr_ul_data; + /* NR dl */ + int nr_dl_rnti; + int nr_dl_frame; + int nr_dl_slot; + int nr_dl_data; + /* NR mib */ + int nr_mib_frame; + int nr_mib_slot; + int nr_mib_data; + /* NR RAR */ + int nr_rar_rnti; + int nr_rar_frame; + int nr_rar_slot; + int nr_rar_data; + /* config */ int no_mib; int no_sib; @@ -58,8 +82,13 @@ typedef struct { int cur_sib; } ev_data; -void trace(ev_data *d, int direction, int rnti_type, int rnti, - int frame, int subframe, void *buf, int bufsize, int preamble) { +/****************************************************************************/ +/* LTE */ +/****************************************************************************/ + +void trace_lte(ev_data *d, int direction, int rnti_type, int rnti, + int frame, int subframe, void *buf, int bufsize, int preamble) +{ ssize_t ret; int fsf; int i; @@ -100,15 +129,17 @@ void trace(ev_data *d, int direction, int rnti_type, int rnti, if (ret != d->buf.osize) abort(); } -void ul(void *_d, event e) { +void ul(void *_d, event e) +{ ev_data *d = _d; - trace(d, DIRECTION_UPLINK, C_RNTI, e.e[d->ul_rnti].i, - e.e[d->ul_frame].i, e.e[d->ul_subframe].i, - e.e[d->ul_data].b, e.e[d->ul_data].bsize, - NO_PREAMBLE); + trace_lte(d, DIRECTION_UPLINK, C_RNTI, e.e[d->ul_rnti].i, + e.e[d->ul_frame].i, e.e[d->ul_subframe].i, + e.e[d->ul_data].b, e.e[d->ul_data].bsize, + NO_PREAMBLE); } -void dl(void *_d, event e) { +void dl(void *_d, event e) +{ ev_data *d = _d; if (e.e[d->dl_rnti].i == 0xffff) { @@ -119,14 +150,15 @@ void dl(void *_d, event e) { d->cur_sib++; } - trace(d, DIRECTION_DOWNLINK, - e.e[d->dl_rnti].i != 0xffff ? C_RNTI : SI_RNTI, e.e[d->dl_rnti].i, - e.e[d->dl_frame].i, e.e[d->dl_subframe].i, - e.e[d->dl_data].b, e.e[d->dl_data].bsize, - NO_PREAMBLE); + trace_lte(d, DIRECTION_DOWNLINK, + e.e[d->dl_rnti].i != 0xffff ? C_RNTI : SI_RNTI, e.e[d->dl_rnti].i, + e.e[d->dl_frame].i, e.e[d->dl_subframe].i, + e.e[d->dl_data].b, e.e[d->dl_data].bsize, + NO_PREAMBLE); } -void mib(void *_d, event e) { +void mib(void *_d, event e) +{ ev_data *d = _d; if (d->no_mib) return; @@ -134,30 +166,141 @@ void mib(void *_d, event e) { if (d->max_mib && d->cur_mib == d->max_mib) return; d->cur_mib++; - trace(d, DIRECTION_DOWNLINK, NO_RNTI, 0, - e.e[d->mib_frame].i, e.e[d->mib_subframe].i, - e.e[d->mib_data].b, e.e[d->mib_data].bsize, - NO_PREAMBLE); + trace_lte(d, DIRECTION_DOWNLINK, NO_RNTI, 0, + e.e[d->mib_frame].i, e.e[d->mib_subframe].i, + e.e[d->mib_data].b, e.e[d->mib_data].bsize, + NO_PREAMBLE); } -void preamble(void *_d, event e) { +void preamble(void *_d, event e) +{ ev_data *d = _d; - trace(d, DIRECTION_UPLINK, NO_RNTI, 0, - e.e[d->preamble_frame].i, e.e[d->preamble_subframe].i, - NULL, 0, - e.e[d->preamble_preamble].i); + trace_lte(d, DIRECTION_UPLINK, NO_RNTI, 0, + e.e[d->preamble_frame].i, e.e[d->preamble_subframe].i, + NULL, 0, + e.e[d->preamble_preamble].i); } -void rar(void *_d, event e) { +void rar(void *_d, event e) +{ ev_data *d = _d; - trace(d, DIRECTION_DOWNLINK, RA_RNTI, e.e[d->rar_rnti].i, - e.e[d->rar_frame].i, e.e[d->rar_subframe].i, - e.e[d->rar_data].b, e.e[d->rar_data].bsize, - NO_PREAMBLE); + trace_lte(d, DIRECTION_DOWNLINK, RA_RNTI, e.e[d->rar_rnti].i, + e.e[d->rar_frame].i, e.e[d->rar_subframe].i, + e.e[d->rar_data].b, e.e[d->rar_data].bsize, + NO_PREAMBLE); } +/****************************************************************************/ +/* NR */ +/****************************************************************************/ + +#define MAC_NR_START_STRING "mac-nr" + +#define MAC_NR_PAYLOAD_TAG 0x01 +#define MAC_NR_RNTI_TAG 0x02 +#define MAC_NR_FRAME_SLOT_TAG 0x07 + +#define NR_FDD_RADIO 1 +#define NR_TDD_RADIO 2 + +#define NR_DIRECTION_UPLINK 0 +#define NR_DIRECTION_DOWNLINK 1 + +#define NR_NO_RNTI 0 +#define NR_RA_RNTI 2 +#define NR_C_RNTI 3 + +void trace_nr(ev_data *d, int direction, int rnti_type, int rnti, + int frame, int slot, void *buf, int bufsize, int preamble) +{ + ssize_t ret; + int i; + d->buf.osize = 0; + PUTS(&d->buf, MAC_NR_START_STRING); + PUTC(&d->buf, NR_TDD_RADIO); + PUTC(&d->buf, direction); + PUTC(&d->buf, rnti_type); + + if (rnti_type == NR_C_RNTI || rnti_type == NR_RA_RNTI) { + PUTC(&d->buf, MAC_NR_RNTI_TAG); + PUTC(&d->buf, (rnti>>8) & 255); + PUTC(&d->buf, rnti & 255); + } + +#if 0 + /* for old versions of wireshark; not sure if correct */ + int fsf = (frame << 4) + slot; + PUTC(&d->buf, 4 /* MAC_NR_FRAME_SUBFRAME_TAG */); + PUTC(&d->buf, (fsf>>8) & 255); + PUTC(&d->buf, fsf & 255); +#else + PUTC(&d->buf, MAC_NR_FRAME_SLOT_TAG); + PUTC(&d->buf, (frame>>8) & 255); + PUTC(&d->buf, frame & 255); + PUTC(&d->buf, (slot>>8) & 255); + PUTC(&d->buf, slot & 255); +#endif + + PUTC(&d->buf, MAC_NR_PAYLOAD_TAG); + + for (i = 0; i < bufsize; i++) + PUTC(&d->buf, ((char *)buf)[i]); + + ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, + (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); + + if (ret != d->buf.osize) abort(); +} + +void nr_ul(void *_d, event e) +{ + ev_data *d = _d; + + trace_nr(d, NR_DIRECTION_UPLINK, NR_C_RNTI, e.e[d->nr_ul_rnti].i, + e.e[d->nr_ul_frame].i, e.e[d->nr_ul_slot].i, + e.e[d->nr_ul_data].b, e.e[d->nr_ul_data].bsize, NO_PREAMBLE); +} + +void nr_dl(void *_d, event e) +{ + ev_data *d = _d; + + trace_nr(d, NR_DIRECTION_DOWNLINK, NR_C_RNTI, e.e[d->nr_dl_rnti].i, + e.e[d->nr_dl_frame].i, e.e[d->nr_dl_slot].i, + e.e[d->nr_dl_data].b, e.e[d->nr_dl_data].bsize, NO_PREAMBLE); +} + +void nr_mib(void *_d, event e) +{ + ev_data *d = _d; + + if (d->no_mib) return; + + if (d->max_mib && d->cur_mib == d->max_mib) return; + + d->cur_mib++; + + trace_nr(d, NR_DIRECTION_DOWNLINK, NR_NO_RNTI, 0, + e.e[d->nr_mib_frame].i, e.e[d->nr_mib_slot].i, + e.e[d->nr_mib_data].b, e.e[d->nr_mib_data].bsize, NO_PREAMBLE); +} + +void nr_rar(void *_d, event e) +{ + ev_data *d = _d; + + trace_nr(d, NR_DIRECTION_DOWNLINK, NR_RA_RNTI, e.e[d->nr_rar_rnti].i, + e.e[d->nr_rar_frame].i, e.e[d->nr_rar_slot].i, + e.e[d->nr_rar_data].b, e.e[d->nr_rar_data].bsize, NO_PREAMBLE); +} + +/****************************************************************************/ +/****************************************************************************/ + void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id, - int preamble_id, int rar_id) { + int preamble_id, int rar_id, + int nr_ul_id, int nr_dl_id, int nr_mib_id, int nr_rar_id) +{ database_event_format f; int i; d->ul_rnti = -1; @@ -174,10 +317,27 @@ void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id, d->preamble_frame = -1; d->preamble_subframe = -1; d->preamble_preamble = -1; - d->rar_rnti = -1; - d->rar_frame = -1; - d->rar_subframe = -1; - d->rar_data = -1; + d->rar_rnti = -1; + d->rar_frame = -1; + d->rar_subframe = -1; + d->rar_data = -1; + + d->nr_ul_rnti = -1; + d->nr_ul_frame = -1; + d->nr_ul_slot = -1; + d->nr_ul_data = -1; + d->nr_dl_rnti = -1; + d->nr_dl_frame = -1; + d->nr_dl_slot = -1; + d->nr_dl_data = -1; + d->nr_mib_frame = -1; + d->nr_mib_slot = -1; + d->nr_mib_data = -1; + d->nr_rar_rnti = -1; + d->nr_rar_frame = -1; + d->nr_rar_slot = -1; + d->nr_rar_data = -1; + #define G(var_name, var_type, var) \ if (!strcmp(f.name[i], var_name)) { \ if (strcmp(f.type[i], var_type)) goto error; \ @@ -247,6 +407,60 @@ void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id, if (d->rar_rnti == -1 || d->rar_frame == -1 || d->rar_subframe == -1 || d->rar_data == -1) goto error; + /* NR ul: rnti, frame, slot, data */ + f = get_format(database, nr_ul_id); + + for (i = 0; i < f.count; i++) { + G("rnti", "int", d->nr_ul_rnti); + G("frame", "int", d->nr_ul_frame); + G("slot", "int", d->nr_ul_slot); + G("data", "buffer", d->nr_ul_data); + } + + if (d->nr_ul_rnti == -1 || d->nr_ul_frame == -1 || d->nr_ul_slot == -1 || + d->nr_ul_data == -1) + goto error; + + /* NR dl: rnti, frame, slot, data */ + f = get_format(database, nr_dl_id); + + for (i = 0; i < f.count; i++) { + G("rnti", "int", d->nr_dl_rnti); + G("frame", "int", d->nr_dl_frame); + G("slot", "int", d->nr_dl_slot); + G("data", "buffer", d->nr_dl_data); + } + + if (d->nr_dl_rnti == -1 || d->nr_dl_frame == -1 || d->nr_dl_slot == -1 || + d->nr_dl_data == -1) + goto error; + + /* NR MIB: frame, slot, data */ + f = get_format(database, nr_mib_id); + + for (i = 0; i < f.count; i++) { + G("frame", "int", d->nr_mib_frame); + G("slot", "int", d->nr_mib_slot); + G("data", "buffer", d->nr_mib_data); + } + + if (d->nr_mib_frame == -1 || d->nr_mib_slot== -1 || d->nr_mib_data == -1) + goto error; + + /* NR RAR: rnti, frame, slot, data */ + f = get_format(database, nr_rar_id); + + for (i = 0; i < f.count; i++) { + G("rnti", "int", d->nr_rar_rnti); + G("frame", "int", d->nr_rar_frame); + G("slot", "int", d->nr_rar_slot); + G("data", "buffer", d->nr_rar_data); + } + + if (d->nr_rar_rnti == -1 || d->nr_rar_frame == -1 || d->nr_rar_slot == -1 || + d->nr_rar_data == -1) + goto error; + #undef G return; error: @@ -254,7 +468,8 @@ error: abort(); } -void *receiver(void *_d) { +void *receiver(void *_d) +{ ev_data *d = _d; int s; char buf[100000]; @@ -279,7 +494,8 @@ void *receiver(void *_d) { return 0; } -void usage(void) { +void usage(void) +{ printf( "options:\n" " -d this option is mandatory\n" @@ -304,14 +520,16 @@ void usage(void) { exit(1); } -int main(int n, char **v) { +int main(int n, char **v) +{ char *database_filename = NULL; char *input_filename = NULL; void *database; event_handler *h; int in; int i; - int ul_id, dl_id, mib_id = -1, preamble_id, rar_id; + int ul_id, dl_id, mib_id, preamble_id, rar_id; + int nr_ul_id, nr_dl_id, nr_mib_id, nr_rar_id; ev_data d; char *ip = DEFAULT_IP; int port = DEFAULT_PORT; @@ -382,6 +600,11 @@ int main(int n, char **v) { on_off(database, "ENB_PHY_INITIATE_RA_PROCEDURE", is_on, 1); on_off(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA", is_on, 1); + on_off(database, "GNB_MAC_UL_PDU_WITH_DATA", is_on, 1); + on_off(database, "GNB_MAC_DL_PDU_WITH_DATA", is_on, 1); + on_off(database, "GNB_PHY_MIB", is_on, 1); + on_off(database, "GNB_MAC_DL_RAR_PDU_WITH_DATA", is_on, 1); + /* activate selected traces */ if (socket_send(in, &mt, 1) == -1 || socket_send(in, &number_of_events, sizeof(int)) == -1 || @@ -398,12 +621,26 @@ int main(int n, char **v) { mib_id = event_id_from_name(database, "ENB_PHY_MIB"); preamble_id = event_id_from_name(database, "ENB_PHY_INITIATE_RA_PROCEDURE"); rar_id = event_id_from_name(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA"); - setup_data(&d, database, ul_id, dl_id, mib_id, preamble_id, rar_id); + + nr_ul_id = event_id_from_name(database, "GNB_MAC_UL_PDU_WITH_DATA"); + nr_dl_id = event_id_from_name(database, "GNB_MAC_DL_PDU_WITH_DATA"); + nr_mib_id = event_id_from_name(database, "GNB_PHY_MIB"); + nr_rar_id = event_id_from_name(database, "GNB_MAC_DL_RAR_PDU_WITH_DATA"); + + setup_data(&d, database, ul_id, dl_id, mib_id, preamble_id, rar_id, + nr_ul_id, nr_dl_id, nr_mib_id, nr_rar_id); + register_handler_function(h, ul_id, ul, &d); register_handler_function(h, dl_id, dl, &d); register_handler_function(h, mib_id, mib, &d); register_handler_function(h, preamble_id, preamble, &d); register_handler_function(h, rar_id, rar, &d); + + register_handler_function(h, nr_ul_id, nr_ul, &d); + register_handler_function(h, nr_dl_id, nr_dl, &d); + register_handler_function(h, nr_mib_id, nr_mib, &d); + register_handler_function(h, nr_rar_id, nr_rar, &d); + d.socket = socket(AF_INET, SOCK_DGRAM, 0); if (d.socket == -1) { @@ -424,8 +661,10 @@ int main(int n, char **v) { if (e.type == -1) break; - if (!(e.type == ul_id || e.type == dl_id || e.type == mib_id || - e.type == preamble_id || e.type == rar_id)) continue; + if (!(e.type == ul_id || e.type == dl_id || e.type == mib_id || + e.type == preamble_id || e.type == rar_id || + e.type == nr_ul_id || e.type == nr_dl_id || + e.type == nr_mib_id || e.type == nr_rar_id)) continue; handle_event(h, e); } diff --git a/common/utils/asn1_conversions.h b/common/utils/asn1_conversions.h index 050c065d9d..82dca54c08 100644 --- a/common/utils/asn1_conversions.h +++ b/common/utils/asn1_conversions.h @@ -101,11 +101,11 @@ static inline uint64_t BIT_STRING_to_uint64(BIT_STRING_t *asn) { shift = ((asn->size - 1) * 8) - asn->bits_unused; for (index = 0; index < (asn->size - 1); index++) { - result |= asn->buf[index] << shift; + result |= ((uint64_t)asn->buf[index]) << shift; shift -= 8; } - result |= asn->buf[index] >> asn->bits_unused; + result |= ((uint64_t)asn->buf[index]) >> asn->bits_unused; return result; } diff --git a/common/utils/memory_pools.c b/common/utils/memory_pools.c deleted file mode 100644 index 9f37e47080..0000000000 --- a/common/utils/memory_pools.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "assertions.h" -#include "memory_pools.h" - -#if T_TRACER - #include - #include "T.h" -#endif - -/*------------------------------------------------------------------------------*/ -const static int mp_debug = 0; - -# define MP_DEBUG(x, args...) do { if (mp_debug) fprintf(stdout, "[MP][D]"x, ##args); fflush (stdout); } \ - while(0) - -/*------------------------------------------------------------------------------*/ -#ifndef CHARS_TO_UINT32 - #define CHARS_TO_UINT32(c1, c2, c3, c4) (((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4)) -#endif - -#define MEMORY_POOL_ITEM_INFO_NUMBER 2 - -/*------------------------------------------------------------------------------*/ -typedef int32_t items_group_position_t; -typedef int32_t items_group_index_t; - -typedef union items_group_positions_u { - uint64_t all; - struct { - items_group_position_t put; - items_group_position_t get; - } ind; -} items_group_positions_t; - -typedef struct items_group_s { - items_group_position_t number_plus_one; - volatile uint32_t minimum; - volatile items_group_positions_t positions; - volatile items_group_index_t *indexes; -} items_group_t; - -/*------------------------------------------------------------------------------*/ -//static const items_group_position_t ITEMS_GROUP_POSITION_INVALID = -1; -static const items_group_index_t ITEMS_GROUP_INDEX_INVALID = -1; - -/*------------------------------------------------------------------------------*/ -typedef uint32_t pool_item_start_mark_t; -typedef uint32_t pool_item_end_mark_t; - -typedef uint32_t memory_pool_data_t; - -typedef uint32_t pool_start_mark_t; - -typedef uint32_t pools_start_mark_t; - -typedef uint8_t pool_id_t; -typedef uint8_t item_status_t; - -typedef struct memory_pool_item_start_s { - pool_item_start_mark_t start_mark; - - pool_id_t pool_id; - item_status_t item_status; - uint16_t info[MEMORY_POOL_ITEM_INFO_NUMBER]; -} memory_pool_item_start_t; - -typedef struct memory_pool_item_end_s { - pool_item_end_mark_t end_mark; -} memory_pool_item_end_t; - -typedef struct memory_pool_item_s { - memory_pool_item_start_t start; - memory_pool_data_t data[0]; - memory_pool_item_end_t end; -} memory_pool_item_t; - -typedef struct memory_pool_s { - pool_start_mark_t start_mark; - - pool_id_t pool_id; - uint32_t item_data_number; - uint32_t pool_item_size; - items_group_t items_group_free; - memory_pool_item_t *items; -} memory_pool_t; - - -typedef struct memory_pools_s { - pools_start_mark_t start_mark; - - uint32_t pools_number; - uint32_t pools_defined; - memory_pool_t *pools; -} memory_pools_t; - -/*------------------------------------------------------------------------------*/ -static const uint32_t MAX_POOLS_NUMBER = 20; -static const uint32_t MAX_POOL_ITEMS_NUMBER = 200 * 1000; -static const uint32_t MAX_POOL_ITEM_SIZE = 100 * 1000; - -static const pool_item_start_mark_t POOL_ITEM_START_MARK = CHARS_TO_UINT32 ('P', 'I', 's', 't'); -static const pool_item_end_mark_t POOL_ITEM_END_MARK = CHARS_TO_UINT32 ('p', 'i', 'E', 'N'); - -static const item_status_t ITEM_STATUS_FREE = 'F'; -static const item_status_t ITEM_STATUS_ALLOCATED = 'a'; - -static const pool_start_mark_t POOL_START_MARK = CHARS_TO_UINT32 ('P', '_', 's', 't'); - -static const pools_start_mark_t POOLS_START_MARK = CHARS_TO_UINT32 ('P', 'S', 's', 't'); - -/*------------------------------------------------------------------------------*/ -static inline uint32_t items_group_number_items (items_group_t *items_group) { - return items_group->number_plus_one - 1; -} - -static inline uint32_t items_group_free_items (items_group_t *items_group) { - items_group_positions_t positions; - uint32_t free_items; - positions.all = items_group->positions.all; - free_items = items_group->number_plus_one + positions.ind.put - positions.ind.get; - free_items %= items_group->number_plus_one; - return free_items; -} - -static inline items_group_index_t items_group_get_free_item (items_group_t *items_group) { - items_group_position_t get_raw; - items_group_position_t put; - items_group_position_t get; - items_group_position_t free_items; - items_group_index_t index = ITEMS_GROUP_INDEX_INVALID; - /* Get current put position */ - put = items_group->positions.ind.put % items_group->number_plus_one; - /* Get current get position and increase it */ - get_raw = __sync_fetch_and_add (&items_group->positions.ind.get, 1); - get = get_raw % items_group->number_plus_one; - - if(put == get) { - /* No more item free, restore previous position */ - __sync_fetch_and_sub (&items_group->positions.ind.get, 1); - } else { - /* Get index at current get position */ - index = items_group->indexes[get]; - - if (index <= ITEMS_GROUP_INDEX_INVALID) { - /* Index has not yet been completely freed, restore previous get position */ - __sync_fetch_and_sub (&items_group->positions.ind.get, 1); - } else { - if (get_raw == items_group->number_plus_one) { - /* Wrap get position */ - __sync_fetch_and_sub (&items_group->positions.ind.get, items_group->number_plus_one); - } - - free_items = items_group_free_items(items_group); - - /* Updates minimum free items if needed */ - while (items_group->minimum > free_items) { - items_group->minimum = free_items; - } - - /* Clear index at current get position to indicate that item is free */ - items_group->indexes[get] = ITEMS_GROUP_INDEX_INVALID; - } - } - - return (index); -} - -static inline int items_group_put_free_item (items_group_t *items_group, items_group_index_t index) { - items_group_position_t put_raw; - items_group_position_t put; - /* Get current put position and increase it */ - put_raw = __sync_fetch_and_add (&items_group->positions.ind.put, 1); - put = put_raw % items_group->number_plus_one; - - if (put_raw == items_group->number_plus_one) { - /* Wrap position */ - __sync_fetch_and_sub (&items_group->positions.ind.put, items_group->number_plus_one); - } - - AssertError (items_group->indexes[put] <= ITEMS_GROUP_INDEX_INVALID, return (EXIT_FAILURE), - "Index at current put position (%d) is not marked as free (%d)!\n", put, items_group->number_plus_one); - /* Save freed item index at current put position */ - items_group->indexes[put] = index; - return (EXIT_SUCCESS); -} - -/*------------------------------------------------------------------------------*/ -static inline memory_pools_t *memory_pools_from_handler (memory_pools_handle_t memory_pools_handle) { - memory_pools_t *memory_pools; - /* Recover memory_pools */ - memory_pools = (memory_pools_t *) memory_pools_handle; - /* Sanity check on passed handle */ - AssertError (memory_pools->start_mark == POOLS_START_MARK, memory_pools = NULL, - "Handle %p is not a valid memory pools handle, start mark is missing!\n", memory_pools_handle); - return (memory_pools); -} - -static inline memory_pool_item_t *memory_pool_item_from_handler (memory_pool_item_handle_t memory_pool_item_handle) { - void *address; - memory_pool_item_t *memory_pool_item; - /* Recover memory_pools */ - address = memory_pool_item_handle - sizeof(memory_pool_item_start_t); - memory_pool_item = (memory_pool_item_t *) address; - /* Sanity check on passed handle */ - AssertError (memory_pool_item->start.start_mark == POOL_ITEM_START_MARK, memory_pool_item = NULL, - "Handle %p is not a valid memory pool item handle, start mark is missing!\n", memory_pool_item); - return (memory_pool_item); -} - -static inline memory_pool_item_t *memory_pool_item_from_index (memory_pool_t *memory_pool, items_group_index_t index) { - void *address; - address = (void *) memory_pool->items; - address += index * memory_pool->pool_item_size; - return (address); -} - -/*------------------------------------------------------------------------------*/ -memory_pools_handle_t memory_pools_create (uint32_t pools_number) { - memory_pools_t *memory_pools; - pool_id_t pool; - AssertFatal (pools_number <= MAX_POOLS_NUMBER, "Too many memory pools requested (%d/%d)!\n", pools_number, MAX_POOLS_NUMBER); /* Limit to a reasonable number of pools */ - /* Allocate memory_pools */ - memory_pools = malloc (sizeof(memory_pools_t)); - AssertFatal (memory_pools != NULL, "Memory pools structure allocation failed!\n"); - /* Initialize memory_pools */ - { - memory_pools->start_mark = POOLS_START_MARK; - memory_pools->pools_number = pools_number; - memory_pools->pools_defined = 0; - /* Allocate pools */ - memory_pools->pools = calloc (pools_number, sizeof(memory_pool_t)); - AssertFatal (memory_pools->pools != NULL, "Memory pools allocation failed!\n"); - - /* Initialize pools */ - for (pool = 0; pool < pools_number; pool++) { - memory_pools->pools[pool].start_mark = POOL_START_MARK; - } - } - return ((memory_pools_handle_t) memory_pools); -} - -char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle) { - memory_pools_t *memory_pools; - pool_id_t pool; - char *statistics; - int printed_chars; - uint32_t allocated_pool_memory; - uint32_t allocated_pools_memory = 0; - items_group_t *items_group; - uint32_t pool_items_size; - /* Recover memory_pools */ - memory_pools = memory_pools_from_handler (memory_pools_handle); - AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - statistics = malloc(memory_pools->pools_defined * 200); - printed_chars = sprintf (&statistics[0], "Pool: size, number, minimum, free, address space and memory used in Kbytes\n"); - - for (pool = 0; pool < memory_pools->pools_defined; pool++) { - items_group = &memory_pools->pools[pool].items_group_free; - allocated_pool_memory = items_group_number_items (items_group) * memory_pools->pools[pool].pool_item_size; - allocated_pools_memory += allocated_pool_memory; - pool_items_size = memory_pools->pools[pool].item_data_number * sizeof(memory_pool_data_t); - printed_chars += sprintf (&statistics[printed_chars], " %2u: %6u, %6u, %6u, %6u, [%p-%p] %6u\n", - pool, pool_items_size, - items_group_number_items (items_group), - items_group->minimum, - items_group_free_items (items_group), - memory_pools->pools[pool].items, - ((void *) memory_pools->pools[pool].items) + allocated_pool_memory, - allocated_pool_memory / (1024)); - } - - printed_chars = sprintf (&statistics[printed_chars], "Pools memory %u Kbytes\n", allocated_pools_memory / (1024)); - return (statistics); -} - -int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t pool_items_number, uint32_t pool_item_size) { - memory_pools_t *memory_pools; - memory_pool_t *memory_pool; - pool_id_t pool; - items_group_index_t item_index; - memory_pool_item_t *memory_pool_item; - AssertFatal (pool_items_number <= MAX_POOL_ITEMS_NUMBER, "Too many items for a memory pool (%u/%d)!\n", pool_items_number, MAX_POOL_ITEMS_NUMBER); /* Limit to a reasonable number of items */ - AssertFatal (pool_item_size <= MAX_POOL_ITEM_SIZE, "Item size is too big for memory pool items (%u/%d)!\n", pool_item_size, MAX_POOL_ITEM_SIZE); /* Limit to a reasonable item size */ - /* Recover memory_pools */ - memory_pools = memory_pools_from_handler (memory_pools_handle); - AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - /* Check number of already created pools */ - AssertFatal (memory_pools->pools_defined < memory_pools->pools_number, "Can not allocate more memory pool (%d)!\n", memory_pools->pools_number); - /* Select pool */ - pool = memory_pools->pools_defined; - memory_pool = &memory_pools->pools[pool]; - /* Initialize pool */ - { - memory_pool->pool_id = pool; - /* Item size in memory_pool_data_t items by excess */ - memory_pool->item_data_number = (pool_item_size + sizeof(memory_pool_data_t) - 1) / sizeof(memory_pool_data_t); - memory_pool->pool_item_size = (memory_pool->item_data_number * sizeof(memory_pool_data_t)) + sizeof(memory_pool_item_t); - memory_pool->items_group_free.number_plus_one = pool_items_number + 1; - memory_pool->items_group_free.minimum = pool_items_number; - memory_pool->items_group_free.positions.ind.put = pool_items_number; - memory_pool->items_group_free.positions.ind.get = 0; - /* Allocate free indexes */ - memory_pool->items_group_free.indexes = malloc(memory_pool->items_group_free.number_plus_one * sizeof(items_group_index_t)); - AssertFatal (memory_pool->items_group_free.indexes != NULL, "Memory pool indexes allocation failed!\n"); - - /* Initialize free indexes */ - for (item_index = 0; item_index < pool_items_number; item_index++) { - memory_pool->items_group_free.indexes[item_index] = item_index; - } - - /* Last index is not allocated */ - memory_pool->items_group_free.indexes[item_index] = ITEMS_GROUP_INDEX_INVALID; - /* Allocate items */ - memory_pool->items = calloc (pool_items_number, memory_pool->pool_item_size); - AssertFatal (memory_pool->items != NULL, "Memory pool items allocation failed!\n"); - - /* Initialize items */ - for (item_index = 0; item_index < pool_items_number; item_index++) { - memory_pool_item = memory_pool_item_from_index (memory_pool, item_index); - memory_pool_item->start.start_mark = POOL_ITEM_START_MARK; - memory_pool_item->start.pool_id = pool; - memory_pool_item->start.item_status = ITEM_STATUS_FREE; - memory_pool_item->data[memory_pool->item_data_number] = POOL_ITEM_END_MARK; - } - } - memory_pools->pools_defined ++; - return (0); -} - -memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_pools_handle, uint32_t item_size, uint16_t info_0, uint16_t info_1) { - memory_pools_t *memory_pools; - memory_pool_item_t *memory_pool_item; - memory_pool_item_handle_t memory_pool_item_handle = NULL; - pool_id_t pool; - items_group_index_t item_index = ITEMS_GROUP_INDEX_INVALID; - /* Recover memory_pools */ - memory_pools = memory_pools_from_handler (memory_pools_handle); - AssertError (memory_pools != NULL, {}, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - - for (pool = 0; pool < memory_pools->pools_defined; pool++) { - if ((memory_pools->pools[pool].item_data_number * sizeof(memory_pool_data_t)) < item_size) { - /* This memory pool has too small items, skip it */ - continue; - } - - item_index = items_group_get_free_item(&memory_pools->pools[pool].items_group_free); - - if (item_index <= ITEMS_GROUP_INDEX_INVALID) { - /* Allocation failed, skip this pool */ - continue; - } else { - /* Allocation succeed, exit searching loop */ - break; - } - } - - if (item_index > ITEMS_GROUP_INDEX_INVALID) { - /* Convert item index into memory_pool_item address */ - memory_pool_item = memory_pool_item_from_index (&memory_pools->pools[pool], item_index); - /* Sanity check on item status, must be free */ - AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_FREE, "Item status is not set to free (%d) in pool %u, item %d!\n", - memory_pool_item->start.item_status, pool, item_index); - memory_pool_item->start.item_status = ITEM_STATUS_ALLOCATED; - memory_pool_item->start.info[0] = info_0; - memory_pool_item->start.info[1] = info_1; - memory_pool_item_handle = memory_pool_item->data; - MP_DEBUG(" Alloc [%2u][%6d]{%6d}, %3u %3u, %6u, %p, %p, %p\n", - pool, item_index, - items_group_free_items (&memory_pools->pools[pool].items_group_free), - info_0, info_1, - item_size, - memory_pools->pools[pool].items, - memory_pool_item, - memory_pool_item_handle); - } else { - MP_DEBUG(" Alloc [--][------]{------}, %3u %3u, %6u, failed!\n", info_0, info_1, item_size); - } - - return memory_pool_item_handle; -} - -int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, uint16_t info_0) { - memory_pools_t *memory_pools; - memory_pool_item_t *memory_pool_item; - pool_id_t pool; - items_group_index_t item_index; - uint32_t item_size; - uint32_t pool_item_size; - uint16_t info_1; - int result; - /* Recover memory_pools */ - memory_pools = memory_pools_from_handler (memory_pools_handle); - AssertError (memory_pools != NULL, return (EXIT_FAILURE), "Failed to retrieve memory pools for handle %p!\n", memory_pools_handle); - /* Recover memory pool item */ - memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle); - AssertError (memory_pool_item != NULL, return (EXIT_FAILURE), "Failed to retrieve memory pool item for handle %p!\n", memory_pool_item_handle); - info_1 = memory_pool_item->start.info[1]; - /* Recover pool index */ - pool = memory_pool_item->start.pool_id; - AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined); - item_size = memory_pools->pools[pool].item_data_number; - pool_item_size = memory_pools->pools[pool].pool_item_size; - item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size; - MP_DEBUG(" Free [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n", - pool, item_index, - items_group_free_items (&memory_pools->pools[pool].items_group_free), - memory_pool_item->start.info[0], info_1, - memory_pool_item_handle, memory_pool_item, - memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t)))); - /* Sanity check on calculated item index */ - AssertFatal (memory_pool_item == memory_pool_item_from_index(&memory_pools->pools[pool], item_index), - "Incorrect memory pool item address (%p, %p) for pool %u, item %d!\n", - memory_pool_item,(void *)memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index); - /* Sanity check on end marker, must still be present (no write overflow) */ - AssertFatal (memory_pool_item->data[item_size] == POOL_ITEM_END_MARK, - "Memory pool item is corrupted, end mark is not present for pool %u, item %d!\n", pool, item_index); - /* Sanity check on item status, must be allocated */ - AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_ALLOCATED, - "Trying to free a non allocated (%x) memory pool item (pool %u, item %d)!\n", - memory_pool_item->start.item_status, pool, item_index); - memory_pool_item->start.item_status = ITEM_STATUS_FREE; - result = items_group_put_free_item(&memory_pools->pools[pool].items_group_free, item_index); - AssertError (result == EXIT_SUCCESS, {}, "Failed to free memory pool item (pool %u, item %d)!\n", pool, item_index); - return (result); -} - -void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, int index, uint16_t info) { - memory_pools_t *memory_pools; - memory_pool_item_t *memory_pool_item; - pool_id_t pool; - items_group_index_t item_index; - uint32_t item_size; - uint32_t pool_item_size; - AssertFatal (index < MEMORY_POOL_ITEM_INFO_NUMBER, "Incorrect info index (%d/%d)!\n", index, MEMORY_POOL_ITEM_INFO_NUMBER); - /* Recover memory pool item */ - memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle); - AssertFatal (memory_pool_item != NULL, "Failed to retrieve memory pool item for handle %p!\n", memory_pool_item_handle); - /* Set info[1] */ - memory_pool_item->start.info[index] = info; - - /* Check item validity and log (not mandatory) */ - if (1) { - /* Recover memory_pools */ - memory_pools = memory_pools_from_handler (memory_pools_handle); - AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - /* Recover pool index */ - pool = memory_pool_item->start.pool_id; - AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined); - item_size = memory_pools->pools[pool].item_data_number; - pool_item_size = memory_pools->pools[pool].pool_item_size; - item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size; - MP_DEBUG(" Info [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n", - pool, item_index, - items_group_free_items (&memory_pools->pools[pool].items_group_free), - memory_pool_item->start.info[0], memory_pool_item->start.info[1], - memory_pool_item_handle, memory_pool_item, - memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t)))); - /* Sanity check on calculated item index */ - AssertFatal (memory_pool_item == memory_pool_item_from_index(&memory_pools->pools[pool], item_index), - "Incorrect memory pool item address (%p, %p) for pool %u, item %d!\n", - memory_pool_item, (void *)memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index); - /* Sanity check on end marker, must still be present (no write overflow) */ - AssertFatal (memory_pool_item->data[item_size] == POOL_ITEM_END_MARK, - "Memory pool item is corrupted, end mark is not present for pool %u, item %d!\n", pool, item_index); - /* Sanity check on item status, must be allocated */ - AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_ALLOCATED, - "Trying to free a non allocated (%x) memory pool item (pool %u, item %d)\n", - memory_pool_item->start.item_status, pool, item_index); - } -} diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index 1680410ebb..e81851c273 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -194,7 +194,8 @@ task_list_t tasks[TASK_MAX]; t->next_timer=UINT64_MAX; // Proceed expired timer - for ( auto it=t->timer_map.begin() ; it != t->timer_map.end() ; ++it ) { + for ( auto it=t->timer_map.begin() , next_it = it; it != t->timer_map.end() ; it = next_it ) { + ++next_it; if ( it->second.timeout < current_time ) { MessageDef *message = itti_alloc_new_message(TASK_TIMER, TIMER_HAS_EXPIRED); message->ittiMsg.timer_has_expired.timer_id=it->first; diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c index 9dd512091d..6a0da678e2 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.c +++ b/common/utils/telnetsrv/telnetsrv_proccmd.c @@ -121,9 +121,11 @@ char toksep[2]; case SCHED_RR: lptr+=sprintf(lptr,"%s ","rt: rr"); break; +#ifdef SCHED_DEADLINE case SCHED_DEADLINE: lptr+=sprintf(lptr,"%s ","rt: deadline"); break; +#endif default: lptr+=sprintf(lptr,"%s ","????"); break; diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md index bc1b1db54a..4db3cd6ad1 100644 --- a/common/utils/threadPool/thread-pool.md +++ b/common/utils/threadPool/thread-pool.md @@ -6,10 +6,9 @@ Each worker loop on pick from the same input queue jobs to do. When a job is done, the worker sends a return if a return is defined. - A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). +A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). - All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, - so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. +All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. ## license Author: @@ -18,65 +17,187 @@ When a job is done, the worker sends a return if a return is defined. # jobs - A job is a message (notifiedFIFO_elt_t): - next: - internal FIFO chain, do not set it - key: - a long int that the client can use to identify a message or a group of messages - responseFifo: - if the client defines a response FIFO, the message will be posted back after processing - processingFunc: - any funtion (type void processingFunc(void *)) that the worker will launch - msgData: - the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing - malloced: - a boolean that enable internal free in these cases: - no return Fifo or Abort feature +A job is a message (notifiedFIFO_elt_t): - The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. +* next: + internal FIFO chain, do not set it +* key: + a long int that the client can use to identify a message or a group of messages +* ResponseFifo: + if the client defines a response FIFO, the message will be posted back after processing +* processingFunc: + any funtion (type void processingFunc(void *)) that the worker will launch +* msgData: + the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing +* malloced: + a boolean that enable internal free in these cases: + no return Fifo or Abort feature + +The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. # Queues of jobs - Queues are type of: - notifiedFIFO_t that must be initialized by init_notifiedFIFO() - No delete function is required, the creator has only to free the data of type notifiedFIFO_t +Queues are type of: - push_notifiedFIFO() add a job in the queue - pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking +* notifiedFIFO_t that must be initialized by init_notifiedFIFO() +* No delete function is required, the creator has only to free the data of type notifiedFIFO_t +* push_notifiedFIFO() add a job in the queue +* pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking +* abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) - abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) +These queues details hereafter + +## Common + +newNotifiedFIFO_elt() + +creates a message, that will later be used in queues/FIFO + +delNotifiedFIFO_elt() + +deletes it + +NotifiedFifoData() + +gives a pointer to the beginning of free usage memory in a message (you can put any data there, up to 'size' parameter you passed to newNotifiedFIFO_elt() + +These 3 calls are not mandatory, you can also use your own memory to save the malloc()/free() that are behind these calls +iFirst level: non thread safe FIFO (or queues) + +# low level: fast and simple + +initNotifiedFIFO_nothreadSafe() + +to create a queue + +pushNotifiedFIFO_nothreadSafe() + +Add a element in a queue + +pullNotifiedFIFO_nothreadSafe() + +pull a element from a queue + +As these queues are not thread safe, there is NO blocking mechanism, neither pull() versus poll() calls + +There is no delete for a message queue: you only have to abandon the memory you allocated to call iinitNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf) + +So if you malloced the memory under 'nf' parameter you have to free it, if it is automatic variable (local variable) or global variable, nothing is to be done. + + +## thread safe queues + +These queues are built on not thread safe queues when we need thread to thread protection + +initNotifiedFIFO() + +to create a queue + +pushNotifiedFIFO() + +Add a element in a queue + +pullNotifiedFIFO() + +pull a element from a queue, this call is blocking until a message arrived + +pollNotifiedFIFO() + +pull a element from a queue, this call is not blocking, so it returns always very shortly + +in 99.9% cases, pull() is better than poll() + +No delete() call, same principle as not thread safe queues # Thread pools ## initialization - The clients can create one or more thread pools with init_tpool() - the params string structure: - describes a list of cores, separated by "," that run a worker thread +The clients can create one or more thread pools with init_tpool() - If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and - the related code (use negative values is allowed, so the thread will never be mapped on a specific core). +the params string structure: describes a list of cores, separated by "," that run a worker thread - The threads are all Linux real time scheduler, their name is set automatically is "Tpool_" +If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core). + +The threads are all Linux real time scheduler, their name is set automatically is "Tpool_" ## adding jobs - The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) +The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) - If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. +If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. ## abort - A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. +A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. - Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. +Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. + +## API details +Each thread pool (there can be several in the same process) should be initialized + +### initTpool(char *params,tpool_t *pool, bool performanceMeas) is to be called oncepool + +the configuration parameter is a string, elements separated by ",": + +* N: if a N is in the parameter list, no threads are created + The purpose is to keep the same API in any case +* a CPU with a little number of cores, + or in debugging sessions to simplify the human work +* a number that represent a valid CPU core on the target CPU + A thread is created and stick on the core (with set affinity) +* a number that is not a valid CPU core + a floating thread is created (Linux is responsible of the real time core allocation) + +example: "-1,-1,-1" +as there is no core number -1, the thread pool is made of 3 floating threads +be careful with fix allocation: it is hard to be more clever than Linux kernel + +pool is the memory you allocated before to store the thread pool internal state (same concept as above queues) + +performanceMeas is a flag to enable measurements (well described in documentation) + +### pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) + +adds a job to do in the thread pool + +The msg data you can set are: + +* key: + a value for you that you will find back in the response + it is also the key for abortTpool() +* reponseFifo + if you set it, the message will be sent back on this queue when the job is done + if you don't set it, no return is performed, the thread pool frees the message 'msg' when the job is done +* processingFunc + the function the job will run. the function prototype is void (void *memory) + the data part (the pointer returned by NotifiedFifoData(msg)) is passed to the function + it is used to send data to the processing function and also to write back results + of course, writing back results will lead you to use also a return queue (the parameter reponseFifo) + +### pullTpool() collects job result in a return queue + +you collect results in one result queue: the message you gave to pushTpool(), nevertheless it has been updated by processingFunc() + +An example of multiple return queues, in eNB: I created one single thread pool (because it depends mainly on CPU hardware), but i use two return queues: one for turbo encode, one for turbo decode. + +### tryPullTpool() + +is the same, but not blocking (pollTpool() would have been a better name) + +### abortTpool() + +Is a facility to cancel work you pushed to a thread pool + +I used it once: when eNB performs turbo decode, I push all segments in the thread pool. + +But when I get back the decoding results, if one segment can't be decoded, I don't need the results of the other segments of the same UE. ## Performance measurements - A performance measurement is integrated: - the pool will automacillay fill timestamps: - - * creationTime: - time the request is push to the pool; +A performance measurement is integrated: +the pool will automacillay fill timestamps: +* creationTime: +time the request is push to the pool; * startProcessingTime: time a worker start to run on the job * endProcessingTime: diff --git a/doc/5Gnas.md b/doc/5Gnas.md new file mode 100644 index 0000000000..3d33af426c --- /dev/null +++ b/doc/5Gnas.md @@ -0,0 +1,107 @@ + + + +This tuto for 5G gNB NAS design +{: .text-center} + +# source files + +executables/ocp-gnb.c: a main loop to create a debuggable gNB, see document SW_archi.md +openair2/RRC/NR/nr_ngap_gNB.c: skeleton for interface with NGAP +openair3/NAS/COMMON/milenage.h: a simple milenage implementation, depend only on crypto library +openair3/NAS/COMMON/NR_NAS_defs.h: messages defined for NAS implemented in C: C struct, C enums and automatic conversion to labels for debug messages +openair3/NAS/COMMON/nr_common.c: 5G NAS common code between gNB and UE +openair3/UICC/usim_interface.c: UICC simulation for USIM messages + +openair3/NAS/NR_UE/ue_process_nas.c: NAS code for UE + +openair3/NAS/gNB/network_process_nas.c: NAS code for gNB running without 5GC + +openair3/TEST/test5Gnas.c: unitary testing of NAS messages: encodes+decode a standard network entry, mixing code from UE and 5GC (or gNB in noCore) + +# USIM simulation +A new USIM simulation, that parameters are in regular OAI config files + +## To open the USIM +init_uicc() takes a parameter: the name of the block in the config file +In case we run several UEs in one process, the variable section name allows to make several UEs configurations in one config file. + +The NAS implementation uses this possibility. + +# UE side +UEprocessNAS() is the entry for all messages. +It decodes the message type and call the specific function for each messgae + +## Identityrequest + IdentityResponse +When the UE receives the request, it stores the 5GC request parameters in the UE context ( UE->uicc pointer) +It calls "scheduleNAS", that would trigger a answer (seeing general archtecture, it will probly be a itti message to future RRC or NGAP thread). + +When the scheduler wants to encode the answer, it calls identityResponse() +The UE search for a section in the config file called "uicc" +it encodes the NAS answer with the IMSI, as a 4G compatible authentication. +A future release would encode 5G SUPI as native 5G UICC. + +## Authenticationrequest + authenticationResponse +When the UE receives the request, it stores the 5GC request parameters in the UE context ( UE->uicc pointer) +It calls "scheduleNAS", that would trigger a answer (seeing general archtecture, it will probly be a itti message to future RRC or NGAP thread). + +When the scheduler wants to encode the answer, it calls authenticationResponse() +The UE search for a section in the config file called "uicc" +It uses the Milenage parameters of this section to encode a milenage response +A future release would encode 5G new authentication cyphering functions. + +## SecurityModeCommand + securityModeComplete +When the UE receives the request it will: +Selected NAS security algorithms: store it for future encoding +Replayed UE security capabilities: check if it is equal to UE capabilities it sent to the 5GC +IMEISV request: to implement +ngKSI: Key set Indicator, similator to 4G to select a ciphering keys set + +When the scheduler wants to encode the answer, it calls registrationComplete() + +## registrationComplete +To be defined in UE, this NAS message is done after RRC sequence completes + +# gNB side +gNB NGAP thread receives the NAS message from PHY layers +In normal mode, it send it to the core network with no decoding. + +Here after, the gNB mode "noCore" processing in gNB: NGAP calls the entry function: processNAS() instead of forwarding the packet to the 5GC + +## RRCModeComplete + Identityrequest +When the gNB completes RRC attach, it sends a first message to NGAP thread. +Normal processing sends NGAP initial UE message, in noCore mode, it should call: identityRequest() that encode the NAS identity request inside the gNB. +The gNB NGAP thread then should call the piece of code that forward the message to the UE as when it receives a NAS message from 5GC. + +## All NAS coming from UE +When NGAP thread receives a NAS message from lower layers, it encapsulates it to forward it to the 5GC. In "noCore" mode it calls processNAS(). + +This function stores in the gNB the NAS data, then it should encode the next message (identity, authentication, security mode) or do nothing (registration complete). + + +
+**Note** +{: .panel-heading} +
+ + +
+
+ diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 23d32effbb..1f8d8cfccf 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -254,9 +254,11 @@ The NAS layer is based on **3GPP 24.301** and implements the following functions The following features are valid for the gNB and the 5G-NR UE. * Static TDD, +* FDD * Normal CP * 30 kHz subcarrier spacing * Bandwidths up to 80MHz (217 Physical Resource Blocks) +* Intermediate downlink and uplink frequencies to interface with IF equipment * Single antenna port (single beam) * Slot format: 14 OFDM symbols in UL or DL * Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 supported) diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 5fb0824565..af4a57041f 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -132,6 +132,42 @@ With the RF simulator (on the same machine): `sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --do-ra --rfsim --parallel-config PARALLEL_SINGLE_THREAD` +## IF setup with OAI + +The -C and -CO flags can be used together at UE side to set custom downlink and uplink FR1 intermediate frequencies for the IF equipment. + +In order to run this setup, the following flags are needed at the UE side: + +`-C` + +`--CO` + +and the following parameters must be configured in the RUs section of the gNB configuration file: + +`if_freq` + +`if_offset` + +### Run OAI with custom DL/UL intermediate frequencies + +The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 at gNB side. + +From the `cmake_targets/ran_build/build` folder: + +gNB on machine 1: + +`sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf` + +UE on machine 2: + +`sudo ./nr-uesoftmodem -C 2169080000 --CO -400000000` + + + + + + + [oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/doc/SW_archi.md b/doc/SW_archi.md new file mode 100644 index 0000000000..dba884dcec --- /dev/null +++ b/doc/SW_archi.md @@ -0,0 +1,256 @@ + + + +This tuto for 5G gNB design, with Open Cells main +{: .text-center} + +# Top file: executables/ocp-gnb.c + +the function main() initializes the data from configuration file + +# The main thread is in ru_thread() +The infinite loop: +## rx_rf() + Collect radio signal samples from RF board + all SDR processing is triggered by I/Q sample reception and it's date (timestamp) + TX I/Q samples will have a date in the future, compared to RX timestamp + called for each 5G NR slot + it blocks until data is available + the internal time comes from the RF board sampling numbers + (each sample has a incremental number representing a very accurate timing) +raw incoming data is in buffer called "rxdata" + We derivate frame number, slot number, ... from the RX timestamp +{: .func2} +## nr_fep_full() +"front end processing" of uplink signal +performs DFT on the signal +same function (duplicates): phy_procedures_gNB_common_RX() +it computes the buffer rxdataF (for frequency) from rxdata (samples over time) +rxdataF is the rxdata in frequency domain, phase aligned +{: .func3} +## gNB_top() +only compute frame numbre, slot number, ... +{: .func3} +## ocp_rxtx() +main processing for both UL and DL +start by calling oai_subframe_ind() that trigger processing in pnf_p7_subframe_ind() purpose ??? +all the context is in the passed structure UL_INFO +the context is not very clear: there is a mutex on it, +but not actual coherency (see below handle_nr_rach() assumes data is up-to-date) +The first part (in NR_UL_indication, uses the data computed by the lower part (phy_procedures_gNB_uespec_RX), but for the **previous** slot +Then, phy_procedures_gNB_uespec_RX will hereafter replace the data for the next run +This is very tricky and not thread safe at all. +{: .func3} + +### NR_UL_indication() +This block processes data already decoded and stored in structures behind UL_INFO +{: .func4} + +* handle_nr_rach() +process data from RACH primary detection +if the input is a UE RACH detection +{: .func4} + * nr_schedule_msg2() +{: .func4} +* handle_nr_uci() +???? +{: .func4} +* handle_nr_ulsch() +handles ulsch data prepared by nr_fill_indication() +{: .func4} +* gNB_dlsch_ulsch_scheduler () +the **scheduler** is called here, see dedicated chapter +{: .func4} +* NR_Schedule_response() +process as per the scheduler decided +{: .func4} + +### L1_nr_prach_procedures() +???? +{: .func4} +### phy_procedures_gNB_uespec_RX() +* nr_decode_pucch0() +actual CCH channel decoding form rxdataF (rx data in frequency domain) +populates UL_INFO.uci_ind, actual uci data is in gNB->pucch +{: .func4} +* nr_rx_pusch() +{: .func4} + * extracts data from rxdataF (frequency transformed received data) +{: .func4} + * nr_pusch_channel_estimation() +{: .func4} + * nr_ulsch_extract_rbs_single() +{: .func4} + * nr_ulsch_scale_channel() +{: .func4} + * nr_ulsch_channel_level() +{: .func4} + * nr_ulsch_channel_compensation() +{: .func4} + * nr_ulsch_compute_llr() +this function creates the "likelyhood ratios" +{: .func4} +* nr_ulsch_procedures() +{: .func4} + * actual ULsch decoding +{: .func4} + * nr_ulsch_unscrambling() + {: .func4} + * nr_ulsch_decoding() + {: .func4} + * nr_fill_indication() +populate the data for the next call to "NR_UL_indication()" +it would be better to call **NR_UL_indication()** now instead of before (on previous slot) +{: .func4} + +### phy_procedures_gNB_TX() +* nr_common_signal_procedures() +generate common signals +{: .func4} +* nr_generate_dci_top() +generate DCI: the scheduling informtion for each UE in both DL and UL +{: .func4} +* nr_generate_pdsch() +generate DL shared channel (user data) +{: .func4} + +### nr_feptx_prec() +tx precoding +{: .func3} +### nr_feptx0 +do the inverse DFT +{: .func3} +### tx_rf() +send radio signal samples to the RF board +the samples numbers are the future time for these samples emission on-air +{: .func3} + +# Scheduler +The scheduler is called by the chain: nr_ul_indication()=>gNB_dlsch_ulsch_scheduler() +It calls sub functions to process each physical channel (rach, ...) +The scheduler uses and internal map of used RB: vrb_map and vrb_map_UL, so each specific channel scheduler can see the already filled RB in each subframe (the function gNB_dlsch_ulsch_scheduler() clears these two arrays when it starts) + +The scheduler also calls "run_pdcp()", as this is not a autonomous thread, it needs to be called here to update traffic requests (DL) and to propagate waiting UL to upper layers +After calling run_pdcp, it updates "rlc" time data but it doesn't actually process rlc +it sends a iiti message to activate the thread for RRC, the answer will be asynchronous in ???? + +Calls schedule_nr_mib() that calls mac_rrc_nr_data_req() to fill MIB, + +Calls each channel allocation: schedule SI, schedule_ul, schedule_dl, ... +this is a major entry for "phy-test" mode: in this mode, the allocation is fixed +all these channels goes to mac_rrc_nr_data_req() to get the data to transmit + +nr_schedule_ue_spec() is called +* calls nr_simple_dlsch_preprocessor()=> mac_rlc_status_ind() mac_rlc_status_ind() locks and checks directly inside rlc data the quantity of waiting data. So, the scheduler can allocate RBs +* calls nr_update_pucch_scheduling() + * get_pdsch_to_harq_feedback() to schedule retransmission in DL + +Calls nr_fill_nfapi_dl_pdu() to actually populate what should be done by the lower layers to make the Tx subframe + +# RRC +RRC is a regular thread with itti loop on queue: TASK_RRC_GNB +it receives it's configuration in message NRRRC_CONFIGURATION_REQ, then real time mesages for all events: S1/NGAP events, X2AP messages and RRC_SUBFRAME_PROCESS + +RRC_SUBFRAME_PROCESS message is send each subframe + +how does it communicate to scheduler ? + + +# RLC +RLC code is new implementation, not using OAI mechanisms: it is implemented directly on pthreads, ignoring OAI common functions. +It is a library, running in thread RRC but also in PHY layer threads and some bits in pdcp running thread or F1 interface threads. + +RLC data is isolated and encapsulated. +It is stored under a global var: nr_rlc_ue_manager +The init function rlc_module_init() populates this global variable. +A small effort could lead us to return the pointer to the caller of rlc_module_init() (internal type: nr_rlc_ue_manager_internal_t) +but it returns void. +It could return the initialized pointer (as FILE* fopen() for example), then the RLC layer could have multiple instances in one process. +Even, a future evolution could remove this global rlc layer: rlc can be only a library that we create a instance for each UE because it doesn't shareany data between UEs. + +For DL (respectively from UL in UE), the scheduler need to know the quantity of data waitin to be sent: it calls mac_rlc_status_ind() +That "peek" the size of the waiting data for a UE. +The scheduler then push orders to lower layers. The transport layer will actually pull data from RLC with: mac_rlc_data_req() +the low layer push data into rlc by: mac_rlc_data_ind() +Still on DL (gNB side), PDCP push incoming data into RLC by calling: rlc_data_req() + +For UL, the low layer push data into rlc by: mac_rlc_data_ind() +Then, rlc push it to pdcp by calling pdcp_data_ind() from a complex rlc internal call back (deliver_sdu()) + +When adding a UE, external code have to call nr_rrc_rlc_config_asn1_req(), to remove it: rrc_rlc_remove_ue() +Inside UE, channels called drd or srb can be created: ??? and deleted: rrc_rlc_config_req() + +nr_rlc_tick() must be called periodically to manage the internal timers + +successful_delivery() and max_retx_reached(): in ??? trigger, the RLC sends a itti message to RRC: RLC_SDU_INDICATION (neutralized by #if 0 right now) + +#PDCP + +The PDCP implementation is also protected through a general mutex. +The design is very similar to rlc layer. The pdcp data is isolated and encapsulated. + +pdcp_layer_init(): same as rlc init +we have to call a second init function: pdcp_module_init() + +At Tx side (DL in gNB), pdcp_data_req() is the entry function that the upper layer calls. +The upper layer can be GTP or a PDCP internal thread enb_tun_read_thread() that read directly from Linux socket in case we skip 3GPP core implementation. +PDCP internals for pdcp_data_req() is thread safe: inside pdcp_data_req_drb(), the pdcp manager protects with the mutex the access to the SDU receiving function of PDCP (recv_sdu() callback, corresponding to nr_pdcp_entity_drb_am_recv_sdu() for DRBs). When it needs, the pdcp layer push this data to rlc by calling : rlc_data_req() + +Also, incoming downlink sdu can comme from internal RRC: in this case, pdcp_run() reads a itti queue, for message RRC_DCCH_DATA_REQ, to0 only call 'pdcp_data_req()' + +At Rx side, pdcp_data_ind() is the entry point that receives the data from RLC. +- Inside pdcp_data_ind(), the pdcp manager mutex protects the access to the PDU receiving function of PDCP (recv_pdu() callback corresponding to nr_pdcp_entity_drb_am_recv_pdu() for DRBs) +- Then deliver_sdu_drb() function sends the received data to GTP thread through an ITTI message (GTPV1U_ENB_TUNNEL_DATA_REQ). + +pdcp_config_set_security(): not yet developped + +nr_DRB_preconfiguration(): the mac layer calls this for ??? + +nr_rrc_pdcp_config_asn1_req() adds a UE in pdcp, pdcp_remove_UE() removes it + +# GTP +Gtp + UDP are two twin threads performing the data plane interface to the core network +The design is hybrid: thread and inside other threads calls. It should at least be protected by a mutex. +## GTP thread +Gtp thread has a itti interface: queue TASK_GTPV1_U +The interface is about full definition: control messages (create/delet GTP tunnels) and data messages (user plane UL and DL). +PDCP layer push to the GTP queue (outside UDP thread that do almost nothing and work only with GTP thread) is to push a UL packet. + + +## GTP thread running code from other layers +gtp thread calls directly pdcp_data_req(), so it runs inside it's context internal pdcp structures updates + +## inside other threads +gtpv1u_create_s1u_tunnel(), delete tunnel, ... functions are called inside the other threads, without mutex. + +# NGAP +NGAP would be a itti thread as is S1AP (+twin thread SCTP that is almost void processing)? +About all messages are exchanged with RRC thread + + +
+**Note** +{: .panel-heading} +
+ + +
+
+ diff --git a/docker/Dockerfile.eNB.rhel8.2 b/docker/Dockerfile.eNB.rhel8.2 index ebd62e49c8..363b070934 100644 --- a/docker/Dockerfile.eNB.rhel8.2 +++ b/docker/Dockerfile.eNB.rhel8.2 @@ -49,6 +49,7 @@ RUN yum update -y && \ nettle \ atlas \ net-tools \ + iputils \ iproute \ libyaml && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -120,3 +121,4 @@ WORKDIR /opt/oai-enb #CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"] #ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.eNB.rhel8.2.oc4-4 b/docker/Dockerfile.eNB.rhel8.2.oc4-4 index b3d9b68af8..039183a0f2 100644 --- a/docker/Dockerfile.eNB.rhel8.2.oc4-4 +++ b/docker/Dockerfile.eNB.rhel8.2.oc4-4 @@ -51,6 +51,7 @@ RUN yum update -y && \ atlas \ net-tools \ iproute \ + iputils \ libyaml && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -121,4 +122,4 @@ WORKDIR /opt/oai-enb #CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"] #ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"] - +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.eNB.ubuntu18 b/docker/Dockerfile.eNB.ubuntu18 index 334ac1b5f2..9b6e5cb47d 100644 --- a/docker/Dockerfile.eNB.ubuntu18 +++ b/docker/Dockerfile.eNB.ubuntu18 @@ -57,6 +57,7 @@ RUN apt-get update && \ libconfig9 \ openssl \ net-tools \ + iputils-ping \ iproute2 \ libyaml-0-2 && \ # Install UHD driver from ettus ppa @@ -120,3 +121,4 @@ WORKDIR /opt/oai-enb #CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"] #ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.enb.rhel7.oc4-4 b/docker/Dockerfile.enb.rhel7.oc4-4 deleted file mode 100644 index 85c2a17ead..0000000000 --- a/docker/Dockerfile.enb.rhel7.oc4-4 +++ /dev/null @@ -1,83 +0,0 @@ -#/* -# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -# * contributor license agreements. See the NOTICE file distributed with -# * this work for additional information regarding copyright ownership. -# * The OpenAirInterface Software Alliance licenses this file to You under -# * the OAI Public License, Version 1.1 (the "License"); you may not use this file -# * except in compliance with the License. -# * You may obtain a copy of the License at -# * -# * http://www.openairinterface.org/?page_id=698 -# * -# * Unless required by applicable law or agreed to in writing, software -# * distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. -# *------------------------------------------------------------------------------- -# * For more information about the OpenAirInterface (OAI) Software Alliance: -# * contact@openairinterface.org -# */ -#--------------------------------------------------------------------- -# -# Dockerfile for the Open-Air-Interface BUILD service -# Valid for RHEL7 in the OpenShift context (v4.4) -# -#--------------------------------------------------------------------- - -FROM image-registry.openshift-image-registry.svc:5000/oai/oai-ran:latest AS enb-build - - -WORKDIR /oai-enb -COPY . . - -#run build_oai to build the target image -RUN /bin/sh oaienv && \ - cd cmake_targets && \ - mkdir -p log && \ - ./build_oai --eNB - - -#start from scratch for target executable -FROM registry.access.redhat.com/ubi7/ubi:latest as oai-enb - -# Entitlements and RHSM configurations are Open-Shift Secret and ConfigMaps -# It is pre-requisite -RUN rm -Rf /etc/rhsm/ca /etc/pki/entitlement -# Copy the entitlements -COPY ./etc-pki-entitlement /etc/pki/entitlement -# Copy the subscription manager configurations -COPY ./rhsm-conf /etc/rhsm -COPY ./rhsm-ca /etc/rhsm/ca - - -#install developers pkg/repo -RUN rm /etc/rhsm-host && \ - # Initialize /etc/yum.repos.d/redhat.repo - # See https://access.redhat.com/solutions/1443553 - yum repolist --disablerepo=* && \ - yum-config-manager --enable rhel-7-server-optional-rpms rhel-server-rhscl-7-rpms && \ - yum update -y && \ - yum install -y \ - lksctp-tools \ - protobuf-c \ - nettle \ - libyaml && \ - echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf - - -WORKDIR /opt/oai-enb/bin -COPY --from=enb-build /oai-enb/targets/bin/lte-softmodem.Rel15 . - -RUN ldd lte-softmodem.Rel15 - -#EXPOSE 2152/udp # S1U, GTP/UDP -#EXPOSE 22100/tcp # ? -#EXPOSE 36412/udp # S1C, SCTP/UDP -#EXPOSE 36422/udp # X2C, SCTP/UDP -#EXPOSE 50000/udp # IF5 / ORI (control) -#EXPOSE 50001/udp # IF5 / ECPRI (data) - -#CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"] -#ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"] - diff --git a/docker/Dockerfile.gNB.rhel8.2 b/docker/Dockerfile.gNB.rhel8.2 index cde171e208..901df9757c 100644 --- a/docker/Dockerfile.gNB.rhel8.2 +++ b/docker/Dockerfile.gNB.rhel8.2 @@ -52,6 +52,8 @@ RUN yum repolist --disablerepo=* && \ atlas \ lksctp-tools \ nettle \ + net-tools \ + iputils \ libyaml && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -123,4 +125,4 @@ WORKDIR /opt/oai-gnb #CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] #ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"] - +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.gNB.rhel8.2.oc4-4 b/docker/Dockerfile.gNB.rhel8.2.oc4-4 index 94d8ca2ea8..197bc2a92a 100644 --- a/docker/Dockerfile.gNB.rhel8.2.oc4-4 +++ b/docker/Dockerfile.gNB.rhel8.2.oc4-4 @@ -53,6 +53,8 @@ RUN yum repolist --disablerepo=* && \ atlas \ lksctp-tools \ nettle \ + net-tools \ + iputils \ libyaml && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -124,4 +126,4 @@ WORKDIR /opt/oai-gnb #CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] #ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"] - +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.gNB.ubuntu18 b/docker/Dockerfile.gNB.ubuntu18 index 8481d49f9f..4135b0e785 100644 --- a/docker/Dockerfile.gNB.ubuntu18 +++ b/docker/Dockerfile.gNB.ubuntu18 @@ -59,6 +59,7 @@ RUN apt-get update && \ openssl \ net-tools \ iproute2 \ + iputils-ping \ libyaml-0-2 && \ # Install UHD driver from ettus ppa # At time of writing, it is 3.14 @@ -121,4 +122,4 @@ WORKDIR /opt/oai-gnb #CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] #ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"] - +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2 index 32bfbfc60b..6b64fdec1e 100644 --- a/docker/Dockerfile.lteUE.rhel8.2 +++ b/docker/Dockerfile.lteUE.rhel8.2 @@ -51,6 +51,7 @@ RUN yum update -y && \ atlas \ iproute \ net-tools \ + iputils \ libyaml && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -114,8 +115,9 @@ RUN ldconfig # Copy the relevant configuration files for eNB WORKDIR /opt/oai-lte-ue/etc COPY --from=lte-ue-build /oai-ran/ci-scripts/conf_files/ue.* . +COPY --from=lte-ue-build /oai-ran/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf ./ue_usim.conf WORKDIR /opt/oai-lte-ue #CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem", "-O", "/opt/oai-lte-ue/etc/enb.conf"] #ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"] - +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.lteUE.rhel8.2.oc4-4 b/docker/Dockerfile.lteUE.rhel8.2.oc4-4 index 431c8caa7f..c390e01e3b 100644 --- a/docker/Dockerfile.lteUE.rhel8.2.oc4-4 +++ b/docker/Dockerfile.lteUE.rhel8.2.oc4-4 @@ -51,6 +51,7 @@ RUN yum update -y && \ atlas \ iproute \ net-tools \ + iputils \ libyaml && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -114,8 +115,9 @@ RUN ldd /usr/local/lib/libdfts.so # Copy the relevant configuration files for eNB WORKDIR /opt/oai-lte-ue/etc COPY --from=lte-ue-build /oai-ran/ci-scripts/conf_files/ue.* . +COPY --from=lte-ue-build /oai-ran/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf ./ue_usim.conf WORKDIR /opt/oai-lte-ue #CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem", "-O", "/opt/oai-lte-ue/etc/enb.conf"] #ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"] - +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18 index 34d2552faf..f1233d6a01 100644 --- a/docker/Dockerfile.lteUE.ubuntu18 +++ b/docker/Dockerfile.lteUE.ubuntu18 @@ -58,6 +58,7 @@ RUN apt-get update && \ libconfig9 \ openssl \ net-tools \ + iputils-ping \ iproute2 \ libyaml-0-2 && \ # Install UHD driver from ettus ppa @@ -114,8 +115,9 @@ RUN ldconfig # Copy the relevant configuration files for eNB WORKDIR /opt/oai-lte-ue/etc COPY --from=lte-ue-build /oai-ran/ci-scripts/conf_files/ue.* ./ +COPY --from=lte-ue-build /oai-ran/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf ./ue_usim.conf WORKDIR /opt/oai-lte-ue #CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem", "-O", "/opt/oai-lte-ue/etc/enb.conf"] #ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"] - +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.nrUE.rhel8.2 b/docker/Dockerfile.nrUE.rhel8.2 index 647ba8ba32..466eeedd40 100644 --- a/docker/Dockerfile.nrUE.rhel8.2 +++ b/docker/Dockerfile.nrUE.rhel8.2 @@ -48,6 +48,8 @@ RUN yum update -y && \ yum install -y --enablerepo="ubi-8-codeready-builder" \ lksctp-tools \ nettle \ + net-tools \ + iputils \ atlas \ libXpm \ libX11 \ @@ -114,4 +116,4 @@ COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* . WORKDIR /opt/oai-nr-ue #CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/enb.conf"] #ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"] - +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.nrUE.rhel8.2.oc4-4 b/docker/Dockerfile.nrUE.rhel8.2.oc4-4 index 0787cb481e..3b09b18b55 100644 --- a/docker/Dockerfile.nrUE.rhel8.2.oc4-4 +++ b/docker/Dockerfile.nrUE.rhel8.2.oc4-4 @@ -49,6 +49,8 @@ RUN yum update -y && \ yum install -y --enablerepo="ubi-8-codeready-builder" \ lksctp-tools \ nettle \ + net-tools \ + iputils \ atlas \ libXpm \ libX11 \ @@ -115,4 +117,4 @@ COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* . WORKDIR /opt/oai-nr-ue #CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/enb.conf"] #ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"] - +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.nrUE.ubuntu18 b/docker/Dockerfile.nrUE.ubuntu18 index 32ffbb833b..eecadacb50 100644 --- a/docker/Dockerfile.nrUE.ubuntu18 +++ b/docker/Dockerfile.nrUE.ubuntu18 @@ -58,6 +58,7 @@ RUN apt-get update && \ libconfig9 \ openssl \ net-tools \ + iputils-ping \ iproute2 \ libyaml-0-2 && \ # Install UHD driver from ettus ppa @@ -114,4 +115,4 @@ COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* . WORKDIR /opt/oai-nr-ue #CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/enb.conf"] #ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"] - +CMD ["sleep", "infinity"] diff --git a/docker/README.md b/docker/README.md index ca19396a49..3966196bb1 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,5 +1,153 @@ ---- - -to be done + + + + + +
+ + + + + + OAI Docker/Podman Build and Usage Procedures +
--- + +**Table of Contents** + +1. [Build Strategy](#1-build-strategy) +2. [File organization](#2-file-organization) +3. [Building using docker under Ubuntu 18.04](#3-building-using-docker-under-ubuntu-1804) +4. [Building using podman under Red Hat Entreprise Linux 8.2](#4-building-using-podman-under-red-hat-entreprise-linux-82) +5. [Running modems using docker under Ubuntu 18.04](#5-running-modems-using-docker-under-ubuntu-1804) +6. [Running modems using podman under Red Hat Entreprise Linux 8.2](#6-running-modems-using-podman-under-red-hat-entreprise-linux-82) + +--- + +# 1. Build Strategy # + +For all platforms, the strategy for building docker/podman images is the same: + +* First we create a common shared image that contains: + - the latest source files (by using the `COPY` function) + - all the means to build an OAI RAN executable + * all packages, compilers, ... + * especially UHD is installed +* Then from this shared image (`ran-build`) we can build target images for: + - eNB + - gNB + - lte-UE + - nr-UE +* These target images will only contain: + - the generated executable (for example `lte-softmodem.Rel15`) + - the generated shared libraries (for example `liboai_usrpdevif.so.Rel15`) + - the needed libraries and packages to run these generated binaries + - Some configuration file templates + - Some tools (such as `ping`, `ifconfig`) + +TO DO: + +- Proper entrypoints +- Proper port exposure +- ... + +# 2. File organization # + +Dockerfiles are named with the following naming convention: `Dockerfile.${target}.${OS-version}.${cluster-version}` + +Targets can be: + +- `ran` for an image named `ran-build` (the shared image) +- `eNB` for an image named `oai-enb` +- `gNB` for an image named `oai-gnb` +- `lteUE` for an image named `oai-lte-ue` +- `nrUE` for an image named `oai-nr-ue` + +The currently-supported OS are: + +- `rhel8.2` for Red Hat Entreprise Linux +- `ubuntu18` for Ubuntu 18.04 LTS + +The currently-supported cluster version is: + +- `rhel8.2.oc4-4` + +We have also `rhel7.oc4-4` support but it will be discontinued soon. + +For more details in build within a Openshift Cluster, see [OpenShift README](../openshift/README.md) for more details. + +# 3. Building using `docker` under Ubuntu 18.04 # + +## 3.1. Pre-requisites ## + +* `git` installed +* `docker-ce` installed +* Pulling `ubuntu:bionic` from DockerHub + +## 3.2. Building the shared image ## + +This can be done starting `2020.w41` tag on the `develop` branch, or any branch that includes that tag. + +```bash +git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git +cd openairinterface5g +git checkout develop +``` + +In our Eurecom/OSA environment we need to pass a GIT proxy. + +```bash +docker build --target ran-build --tag ran-build:latest --file docker/Dockerfile.ran.ubuntu18 --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . +``` + +if you don't need it, do NOT pass any value: + +```bash +docker build --target ran-build --tag ran-build:latest --file docker/Dockerfile.ran.ubuntu18 . +``` + +After a while: + +```bash +docker image ls +REPOSITORY TAG IMAGE ID CREATED SIZE +ran-build latest ccb721bc0b57 1 minute ago 4.06GB +... +``` + +## 3.3. Building any target image ## + +For example, the eNB: + +```bash +docker build --target oai-enb --tag oai-enb:latest --file docker/Dockerfile.eNB.ubuntu18 . +``` + +After a while: + +``` +docker image ls +REPOSITORY TAG IMAGE ID CREATED SIZE +oai-enb latest 25ddbd8b7187 1 minute ago 516MB + 875ea3b05b60 8 minutes ago 8.18GB +ran-build latest ccb721bc0b57 1 hour ago 4.06GB +``` + +Do not forget to remove the temporary image: + +``` +docker image prune --force +``` + +# 4. Building using `podman` under Red Hat Entreprise Linux 8.2 # + +TODO. + +# 5. Running modems using `docker` under Ubuntu 18.04 # + +TODO. + +# 6. Running modems using `podman` under Red Hat Entreprise Linux 8.2 # + +TODO. diff --git a/executables/main-fs6.c b/executables/main-fs6.c index c0836943ed..5283ce5eaa 100644 --- a/executables/main-fs6.c +++ b/executables/main-fs6.c @@ -435,7 +435,7 @@ void pusch_procedures_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eN if ((ulsch) && (ulsch->rnti>0) && (ulsch_harq->status == ACTIVE) && - ((ulsch_harq->frame == frame) || (ulsch_harq->repetition_number >1) ) && + ((ulsch_harq->frame == frame) || (ulsch_harq->repetition_number >1) ) && ((ulsch_harq->subframe == subframe) || (ulsch_harq->repetition_number >1) ) && (ulsch_harq->handled == 0)) { // UE has ULSCH scheduling @@ -1520,7 +1520,7 @@ void *cu_fs6(void *arg) { remoteIP[i]=0; break; } - + AssertFatal(createUDPsock(NULL, CU_PORT, remoteIP, port_def, &sockFS6), ""); L1_rxtx_proc_t L1proc= {0}; // We pick the global thread pool from the legacy code global vars diff --git a/executables/main-ocp.c b/executables/main-ocp.c index a0fc42636b..6e5857d6d1 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -78,9 +78,18 @@ int otg_enabled; uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int split73; +int usrp_tx_thread = 0; char * split73_config; int split73; -int usrp_tx_thread = 0; +AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]= {0}; +AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]= {0}; +void flexran_agent_slice_update(mid_t module_idP) { +} +int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p){ + return 0; +} +void proto_agent_stop(mod_id_t mod_id){ +} static void *ru_thread( void *param ); void kill_RU_proc(RU_t *ru) { @@ -101,21 +110,6 @@ void exit_function(const char *file, const char *function, const int line, const close_log_mem(); oai_exit = 1; - if (RC.ru == NULL) - exit(-1); // likely init not completed, prevent crash or hang, exit now... - - for (int ru_id=0; ru_idrfdevice.trx_end_func) { - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - RC.ru[ru_id]->rfdevice.trx_end_func = NULL; - } - - if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) { - RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); - RC.ru[ru_id]->ifdevice.trx_end_func = NULL; - } - } - sleep(1); //allow lte-softmodem threads to exit first exit(1); } @@ -399,6 +393,7 @@ int setup_RU_buffers(RU_t *ru) { return(0); } +#if 0 void init_precoding_weights(PHY_VARS_eNB *eNB) { int layer,ru_id,aa,re,ue,tb; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; @@ -431,6 +426,7 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) { } } } +#endif void ocp_rx_prach(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, @@ -804,8 +800,7 @@ int init_rf(RU_t *ru) { return ret; } -void init_RU(char *rf_config_file, int send_dmrssync) { - RU_t *ru; +void ocp_init_RU(RU_t *ru, char *rf_config_file, int send_dmrssync) { PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL; int i; int CC_id; @@ -821,11 +816,8 @@ void init_RU(char *rf_config_file, int send_dmrssync) { LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); - for (int ru_id=0; ru_idrf_config_file = rf_config_file; - ru->idx = ru_id; + ru->idx = 0; ru->ts_offset = 0; if (ru->is_slave == 1) { @@ -849,8 +841,6 @@ void init_RU(char *rf_config_file, int send_dmrssync) { ru->wakeup_L1_sleep_cnt_max = 3; if (ru->num_eNB > 0) { - LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", - __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); AssertFatal(ru->eNB_list[0], "ru->eNB_list is not initialized\n"); } else { LOG_E(PHY,"Wrong data model, assigning eNB 0, carrier 0 to RU 0\n"); @@ -867,20 +857,19 @@ void init_RU(char *rf_config_file, int send_dmrssync) { int ruIndex=eNB0->num_RU++; eNB0->RU_list[ruIndex] = ru; } - } // for ru_id } void stop_RU(int nb_ru) { for (int inst = 0; inst < nb_ru; inst++) { LOG_I(PHY, "Stopping RU %d processing threads\n", inst); - kill_RU_proc(RC.ru[inst]); + //kill_RU_proc(RC.ru[inst]); } } /* --------------------------------------------------------*/ /* from here function to use configuration module */ static int DEFBFW[] = {0x00007fff}; -void RCconfig_RU(void) { +void ocpRCconfig_RU(RU_t* ru) { paramdef_t RUParams[] = RUPARAMS_DESC; paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL); @@ -891,87 +880,74 @@ void RCconfig_RU(void) { return; } // setting != NULL - if ( RC.ru != NULL ) { - LOG_W(PHY, "Calling RCconfig_RU twice (nb ru=%d), ignoring the second call data structure is %p\n", - RUParamList.numelt,RC.ru); - return; + ru->idx = 0; + ru->if_timing = synch_to_ext_device; + paramdef_t *vals=RUParamList.paramarray[0]; + + if (RC.nb_L1_inst >0) + ru->num_eNB = vals[RU_ENB_LIST_IDX].numelt; + else + ru->num_eNB = 0; + + for (int i=0; inum_eNB; i++) + ru->eNB_list[i] = RC.eNB[vals[RU_ENB_LIST_IDX].iptr[i]][0]; + + if (config_isparamset(vals, RU_SDR_ADDRS)) { + ru->openair0_cfg.sdr_addrs = strdup(*(vals[RU_SDR_ADDRS].strptr)); } - RC.ru = (RU_t **)malloc(RC.nb_RU*sizeof(RU_t *)); - - for (int j = 0; j < RC.nb_RU; j++) { - RC.ru[j] = (RU_t *)calloc(sizeof(RU_t), 1); - RC.ru[j]->idx = j; - LOG_I(PHY,"Creating RC.ru[%d]:%p\n", j, RC.ru[j]); - RC.ru[j]->if_timing = synch_to_ext_device; - paramdef_t *vals=RUParamList.paramarray[j]; - - if (RC.nb_L1_inst >0) - RC.ru[j]->num_eNB = vals[RU_ENB_LIST_IDX].numelt; - else - RC.ru[j]->num_eNB = 0; - - for (int i=0; inum_eNB; i++) - RC.ru[j]->eNB_list[i] = RC.eNB[vals[RU_ENB_LIST_IDX].iptr[i]][0]; - - if (config_isparamset(vals, RU_SDR_ADDRS)) { - RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(vals[RU_SDR_ADDRS].strptr)); - } - - if (config_isparamset(vals, RU_SDR_CLK_SRC)) { - char *paramVal=*(vals[RU_SDR_CLK_SRC].strptr); - LOG_D(PHY, "RU clock source set as %s\n", paramVal); - - if (strcmp(paramVal, "internal") == 0) { - RC.ru[j]->openair0_cfg.clock_source = internal; - } else if (strcmp(paramVal, "external") == 0) { - RC.ru[j]->openair0_cfg.clock_source = external; - } else if (strcmp(paramVal, "gpsdo") == 0) { - RC.ru[j]->openair0_cfg.clock_source = gpsdo; - } else { - LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", paramVal); - } - } - - if (strcmp(*(vals[RU_LOCAL_RF_IDX].strptr), "yes") == 0) { - if ( !(config_isparamset(vals,RU_LOCAL_IF_NAME_IDX)) ) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = eNodeB_3GPP; - LOG_I(PHY, "Setting function for RU %d to eNodeB_3GPP\n",j); - } else { - RC.ru[j]->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr)); - RC.ru[j]->eth_params.my_addr = strdup(*(vals[RU_LOCAL_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.remote_addr = strdup(*(vals[RU_REMOTE_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.my_portc = *(vals[RU_LOCAL_PORTC_IDX].uptr); - RC.ru[j]->eth_params.remote_portc = *(vals[RU_REMOTE_PORTC_IDX].uptr); - RC.ru[j]->eth_params.my_portd = *(vals[RU_LOCAL_PORTD_IDX].uptr); - RC.ru[j]->eth_params.remote_portd = *(vals[RU_REMOTE_PORTD_IDX].uptr); - } - - RC.ru[j]->max_pdschReferenceSignalPower = *(vals[RU_MAX_RS_EPRE_IDX].uptr);; - RC.ru[j]->max_rxgain = *(vals[RU_MAX_RXGAIN_IDX].uptr); - RC.ru[j]->num_bands = vals[RU_BAND_LIST_IDX].numelt; - /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */ - RC.ru[j]->sf_extension = *(vals[RU_SF_EXTENSION_IDX].uptr); - RC.ru[j]->end_of_burst_delay = *(vals[RU_END_OF_BURST_DELAY_IDX].uptr); - - for (int i=0; inum_bands; i++) RC.ru[j]->band[i] = vals[RU_BAND_LIST_IDX].iptr[i]; + if (config_isparamset(vals, RU_SDR_CLK_SRC)) { + char *paramVal=*(vals[RU_SDR_CLK_SRC].strptr); + LOG_D(PHY, "RU clock source set as %s\n", paramVal); + + if (strcmp(paramVal, "internal") == 0) { + ru->openair0_cfg.clock_source = internal; + } else if (strcmp(paramVal, "external") == 0) { + ru->openair0_cfg.clock_source = external; + } else if (strcmp(paramVal, "gpsdo") == 0) { + ru->openair0_cfg.clock_source = gpsdo; } else { - LOG_I(PHY,"RU %d: Transport %s\n",j,*(vals[RU_TRANSPORT_PREFERENCE_IDX].strptr)); - RC.ru[j]->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr)); - RC.ru[j]->eth_params.my_addr = strdup(*(vals[RU_LOCAL_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.remote_addr = strdup(*(vals[RU_REMOTE_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.my_portc = *(vals[RU_LOCAL_PORTC_IDX].uptr); - RC.ru[j]->eth_params.remote_portc = *(vals[RU_REMOTE_PORTC_IDX].uptr); - RC.ru[j]->eth_params.my_portd = *(vals[RU_LOCAL_PORTD_IDX].uptr); - RC.ru[j]->eth_params.remote_portd = *(vals[RU_REMOTE_PORTD_IDX].uptr); + LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", paramVal); + } + } + + if (strcmp(*(vals[RU_LOCAL_RF_IDX].strptr), "yes") == 0) { + if ( !(config_isparamset(vals,RU_LOCAL_IF_NAME_IDX)) ) { + ru->if_south = LOCAL_RF; + ru->function = eNodeB_3GPP; + } else { + ru->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr)); + ru->eth_params.my_addr = strdup(*(vals[RU_LOCAL_ADDRESS_IDX].strptr)); + ru->eth_params.remote_addr = strdup(*(vals[RU_REMOTE_ADDRESS_IDX].strptr)); + ru->eth_params.my_portc = *(vals[RU_LOCAL_PORTC_IDX].uptr); + ru->eth_params.remote_portc = *(vals[RU_REMOTE_PORTC_IDX].uptr); + ru->eth_params.my_portd = *(vals[RU_LOCAL_PORTD_IDX].uptr); + ru->eth_params.remote_portd = *(vals[RU_REMOTE_PORTD_IDX].uptr); + } + + ru->max_pdschReferenceSignalPower = *(vals[RU_MAX_RS_EPRE_IDX].uptr);; + ru->max_rxgain = *(vals[RU_MAX_RXGAIN_IDX].uptr); + ru->num_bands = vals[RU_BAND_LIST_IDX].numelt; + /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */ + ru->sf_extension = *(vals[RU_SF_EXTENSION_IDX].uptr); + ru->end_of_burst_delay = *(vals[RU_END_OF_BURST_DELAY_IDX].uptr); + + for (int i=0; inum_bands; i++) + ru->band[i] = vals[RU_BAND_LIST_IDX].iptr[i]; + } else { + ru->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr)); + ru->eth_params.my_addr = strdup(*(vals[RU_LOCAL_ADDRESS_IDX].strptr)); + ru->eth_params.remote_addr = strdup(*(vals[RU_REMOTE_ADDRESS_IDX].strptr)); + ru->eth_params.my_portc = *(vals[RU_LOCAL_PORTC_IDX].uptr); + ru->eth_params.remote_portc = *(vals[RU_REMOTE_PORTC_IDX].uptr); + ru->eth_params.my_portd = *(vals[RU_LOCAL_PORTD_IDX].uptr); + ru->eth_params.remote_portd = *(vals[RU_REMOTE_PORTD_IDX].uptr); } /* strcmp(local_rf, "yes") != 0 */ - RC.ru[j]->nb_tx = *(vals[RU_NB_TX_IDX].uptr); - RC.ru[j]->nb_rx = *(vals[RU_NB_RX_IDX].uptr); - RC.ru[j]->att_tx = *(vals[RU_ATT_TX_IDX].uptr); - RC.ru[j]->att_rx = *(vals[RU_ATT_RX_IDX].uptr); - }// j=0..num_rus + ru->nb_tx = *(vals[RU_NB_TX_IDX].uptr); + ru->nb_rx = *(vals[RU_NB_RX_IDX].uptr); + ru->att_tx = *(vals[RU_ATT_TX_IDX].uptr); + ru->att_rx = *(vals[RU_ATT_RX_IDX].uptr); return; } @@ -1055,13 +1031,13 @@ void init_pdcp(void) { pdcp_module_init(pdcp_initmask); if (NODE_IS_CU(RC.rrc[0]->node_type)) { - pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req); + //pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req); } else { pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); } } else { - pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind); + //pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind); } } @@ -1087,16 +1063,11 @@ void terminate_task(module_id_t mod_id, task_id_t from, task_id_t to) { int stop_L1L2(module_id_t enb_id) { LOG_W(ENB_APP, "stopping lte-softmodem\n"); - if (!RC.ru) { - LOG_UI(ENB_APP, "no RU configured\n"); - return -1; - } - /* these tasks need to pick up new configuration */ terminate_task(enb_id, TASK_ENB_APP, TASK_RRC_ENB); oai_exit = 1; LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); - kill_RU_proc(RC.ru[enb_id]); + //kill_RU_proc(RC.ru[enb_id]); LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); kill_eNB_proc(enb_id); oai_exit = 0; @@ -1106,7 +1077,7 @@ int stop_L1L2(module_id_t enb_id) { phy_free_lte_eNB(RC.eNB[enb_id][cc_id]); } - phy_free_RU(RC.ru[enb_id]); + //phy_free_RU(RC.ru[enb_id]); free_lte_top(); return 0; } @@ -1115,14 +1086,18 @@ int stop_L1L2(module_id_t enb_id) { * Restart the lte-softmodem after it has been soft-stopped with stop_L1L2() */ int restart_L1L2(module_id_t enb_id) { - RU_t *ru = RC.ru[enb_id]; + RU_t *ru = NULL; //RC.ru[enb_id]; MessageDef *msg_p = NULL; LOG_W(ENB_APP, "restarting lte-softmodem\n"); /* block threads */ pthread_mutex_lock(&sync_mutex); sync_var = -1; pthread_mutex_unlock(&sync_mutex); - RC.ru_mask |= (1 << ru->idx); + + /* copy the changed frame parameters to the RU */ + /* TODO this should be done for all RUs associated to this eNB */ + memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS)); + /* reset the list of connected UEs in the MAC, since in this process with * loose all UEs (have to reconnect) */ init_UE_info(&RC.mac[enb_id]->UE_info); @@ -1135,11 +1110,6 @@ int restart_L1L2(module_id_t enb_id) { 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); - /* TODO XForms might need to be restarted, but it is currently (09/02/18) - * broken, so we cannot test it */ - init_RU_proc(ru); - ru->rf_map.card = 0; - ru->rf_map.chain = 0; /* CC_id + chain_offset;*/ init_eNB_afterRU(); printf("Sending sync to all threads\n"); pthread_mutex_lock(&sync_mutex); @@ -1187,10 +1157,16 @@ int main ( int argc, char **argv ) { RCconfig_L1(); } + // RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator. + // but RU thread deals with pre_scd and this is necessary in VNF and simulator. + // some initialization is necessary and init_ru_vnf do this. + RU_t ru; + + /* We need to read RU configuration before FlexRAN starts so it knows what * splits to report. Actual RU start comes later. */ - if (RC.nb_RU > 0 && NFAPI_MODE != NFAPI_MODE_VNF) { - RCconfig_RU(); + if ( NFAPI_MODE != NFAPI_MODE_VNF) { + ocpRCconfig_RU(&ru); LOG_I(PHY, "number of L1 instances %d, number of RU %d, number of CPU cores %d\n", RC.nb_L1_inst, RC.nb_RU, get_nprocs()); @@ -1211,7 +1187,7 @@ int main ( int argc, char **argv ) { if (RC.nb_inst > 0) { /* Start the agent. If it is turned off in the configuration, it won't start */ for (i = 0; i < RC.nb_inst; i++) { - flexran_agent_start(i); + //flexran_agent_start(i); } /* initializes PDCP and sets correct RLC Request/PDCP Indication callbacks @@ -1292,20 +1268,16 @@ int main ( int argc, char **argv ) { printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); - // RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator. - // but RU thread deals with pre_scd and this is necessary in VNF and simulator. - // some initialization is necessary and init_ru_vnf do this. + if (RC.nb_RU >0 && NFAPI_MODE!=NFAPI_MODE_VNF) { printf("Initializing RU threads\n"); - init_RU(get_softmodem_params()->rf_config_file, + ocp_init_RU(&ru, + get_softmodem_params()->rf_config_file, get_softmodem_params()->send_dmrs_sync); - for (int ru_id=0; ru_idrf_map.card=0; - RC.ru[ru_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); - LOG_I(PHY,"Starting ru_thread %d\n",ru_id); - init_RU_proc(RC.ru[ru_id]); - } + ru.rf_map.card=0; + ru.rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); + init_RU_proc(&ru); config_sync_var=0; @@ -1316,6 +1288,7 @@ int main ( int argc, char **argv ) { LOG_I(ENB_APP,"RC.nb_RU:%d\n", RC.nb_RU); // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration) printf("ALL RUs ready - init eNBs\n"); + sleep(1); if (NFAPI_MODE!=NFAPI_MODE_PNF && NFAPI_MODE!=NFAPI_MODE_VNF) { LOG_I(ENB_APP,"Not NFAPI mode - call init_eNB_afterRU()\n"); @@ -1369,10 +1342,6 @@ int main ( int argc, char **argv ) { } } - for (int inst = 0; inst < RC.nb_RU; inst++) { - phy_free_RU(RC.ru[inst]); - } - free_lte_top(); end_configmodule(); pthread_cond_destroy(&sync_cond); @@ -1381,17 +1350,6 @@ int main ( int argc, char **argv ) { pthread_mutex_destroy(&nfapi_sync_mutex); pthread_mutex_destroy(&ue_pf_po_mutex); - for(int ru_id=0; ru_idrfdevice.trx_end_func) { - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - RC.ru[ru_id]->rfdevice.trx_end_func = NULL; - } - - if (RC.ru[ru_id]->ifdevice.trx_end_func) { - RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); - RC.ru[ru_id]->ifdevice.trx_end_func = NULL; - } - } } terminate_opt(); diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index a80410112b..bd4a1a72aa 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -48,6 +48,7 @@ #include "SCHED_NR/sched_nr.h" #include "SCHED_NR/fapi_nr_l1.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" +#include "PHY/MODULATION/nr_modulation.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -256,6 +257,15 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t // Do PRACH RU processing L1_nr_prach_procedures(gNB,frame_rx,slot_rx); + + //apply the rx signal rotation here + apply_nr_rotation_ul(&gNB->frame_parms, + gNB->common_vars.rxdataF[0], + slot_rx, + 0, + gNB->frame_parms.Ncp==EXTENDED?12:14, + gNB->frame_parms.ofdm_symbol_size); + phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); } @@ -266,7 +276,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t // run PHY TX procedures the one after the other for all CCs to avoid race conditions // (may be relaxed in the future for performance reasons) // ***************************************** - + if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) { diff --git a/executables/nr-ru.c b/executables/nr-ru.c index ede6ff2458..feff0c29c2 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -623,6 +623,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { unsigned int rxs; int i; uint32_t samples_per_slot = fp->get_samples_per_slot(*slot,fp); + uint32_t samples_per_slot_prev ; openair0_timestamp ts,old_ts; AssertFatal(*slotslots_per_frame && *slot>=0, "slot %d is illegal (%d)\n",*slot,fp->slots_per_frame); @@ -658,16 +659,16 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { ru->ts_offset = proc->timestamp_rx; proc->timestamp_rx = 0; } else { - if (proc->timestamp_rx - old_ts != fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp)) { - LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot,ru->ts_offset); - ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot); + samples_per_slot_prev = fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp); + if (proc->timestamp_rx - old_ts != samples_per_slot_prev) { + LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot_prev,ru->ts_offset); + ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot_prev); proc->timestamp_rx = ts-ru->ts_offset; } } proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023; - uint32_t idx_sf = proc->timestamp_rx / fp->samples_per_subframe; - proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((float)(proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); + proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx,fp); // synchronize first reception to frame 0 subframe 0 LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", ru->idx, @@ -688,7 +689,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { } if (proc->frame_rx != *frame) { - LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",(long long unsigned int)proc->timestamp_rx,proc->frame_rx,*frame); + LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, proc->tti_rx %d, slot %d)\n",(long long unsigned int)proc->timestamp_rx,proc->frame_rx,*frame,proc->tti_rx,*slot); exit_fun("Exiting"); } } else { @@ -727,38 +728,34 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { //nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame); if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT || IS_SOFTMODEM_RFSIM) { - if(slot_type == NR_MIXED_SLOT) { - txsymb = 0; - for(int symbol_count =0;symbol_counttdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) - txsymb++; + if (cfg->cell_config.frame_duplex_type.value == TDD){ + if(slot_type == NR_MIXED_SLOT) { + txsymb = 0; + for(int symbol_count = 0; symbol_counttdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value == 0) + txsymb++; + } + AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb); + if(slot%(fp->slots_per_subframe/2)) + siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + else + siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + //+ ru->end_of_burst_delay; + flags = 3; // end of burst } - AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb); - if(slot%(fp->slots_per_subframe/2)) - siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples); - else - siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); - //+ ru->end_of_burst_delay; - flags=3; // end of burst - } - if (cfg->cell_config.frame_duplex_type.value == TDD && - slot_type == NR_DOWNLINK_SLOT && - prevslot_type == NR_UPLINK_SLOT) { - flags = 2; // start of burst - } + if (slot_type == NR_DOWNLINK_SLOT && prevslot_type == NR_UPLINK_SLOT) + flags = 2; // start of burst - if (cfg->cell_config.frame_duplex_type.value == TDD && - slot_type == NR_DOWNLINK_SLOT && - nextslot_type == NR_UPLINK_SLOT) { - flags = 3; // end of burst + if (slot_type == NR_DOWNLINK_SLOT && nextslot_type == NR_UPLINK_SLOT) + flags = 3; // end of burst } if (fp->freq_range==nr_FR2) { // the beam index is written in bits 8-10 of the flags // bit 11 enables the gpio programming int beam=0; - if (slot==0) beam = 11; //3 for boresight & 8 to enable + //if (slot==0) beam = 11; //3 for boresight & 8 to enable /* if (slot==0 || slot==40) beam=0&8; if (slot==10 || slot==50) beam=1&8; @@ -767,7 +764,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { */ flags |= beam<<8; } - + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); @@ -861,9 +858,9 @@ void *ru_thread_prach( void *param ) { if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); + /*VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); - /*if (ru->gNB_list[0]){ + if (ru->gNB_list[0]){ prach_procedures( ru->gNB_list[0],0 ); @@ -1149,19 +1146,22 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { if (ru->if_frequency == 0) { cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; - } - else { + } else if (ru->if_freq_offset){ + cfg->tx_freq[i] = (double)(ru->if_frequency); + cfg->rx_freq[i] = (double)(ru->if_frequency + ru->if_freq_offset); + LOG_I(PHY, "Setting IF TX frequency to %lu Hz with IF RX frequency offset %d Hz\n", ru->if_frequency, ru->if_freq_offset); + } else { cfg->tx_freq[i] = (double)ru->if_frequency; cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq); } cfg->tx_gain[i] = ru->att_tx; cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx; cfg->configFilename = rf_config_file; - printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", + LOG_I(PHY, "Channel %d: setting tx_gain offset %f, rx_gain offset %f, tx_freq %lu Hz, rx_freq %lu Hz\n", i, cfg->tx_gain[i], cfg->rx_gain[i], - cfg->tx_freq[i], - cfg->rx_freq[i]); + (unsigned long)cfg->tx_freq[i], + (unsigned long)cfg->rx_freq[i]); } } @@ -2220,7 +2220,7 @@ void set_function_spec_param(RU_t *ru) { case REMOTE_IF4p5: ru->do_prach = 0; ru->feprx = NULL; // DFTs - ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // Precoding operation + ru->feptx_prec = nr_feptx_prec; // Precoding operation ru->feptx_ofdm = NULL; // no OFDM mod ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission @@ -2494,6 +2494,7 @@ void RCconfig_RU(void) RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); RC.ru[j]->if_frequency = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr); + RC.ru[j]->if_freq_offset = *(RUParamList.paramarray[j][RU_IF_FREQ_OFFSET].iptr); if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index c0ac1c4c04..fb757a9f47 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -981,7 +981,7 @@ if(!IS_SOFTMODEM_NOS1) // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration) printf("ALL RUs ready - init gNBs\n"); if(IS_SOFTMODEM_DOFORMS) { - + sleep(1); scopeParms_t p; p.argc=&argc; p.argv=argv; diff --git a/executables/nr-ue.c b/executables/nr-ue.c index ee61df86e7..5191551ea3 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -135,17 +135,15 @@ typedef enum { void init_nr_ue_vars(PHY_VARS_NR_UE *ue, - NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag) { int nb_connected_gNB = 1, gNB_id; - memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS)); - ue->Mod_id = UE_id; ue->mac_enabled = 1; + ue->if_inst = nr_ue_if_module_init(0); // Setting UE mode to NOT_SYNCHED by default for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){ @@ -158,6 +156,9 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, // intialize transport init_nr_ue_transport(ue, abstraction_flag); + + // init N_TA offset + init_N_TA_offset(ue); } /*! @@ -175,24 +176,30 @@ static void UE_synch(void *arg) { int i, hw_slot_offset; PHY_VARS_NR_UE *UE = syncD->UE; sync_mode_t sync_mode = pbch; - int CC_id = UE->CC_id; - int freq_offset=0; + //int CC_id = UE->CC_id; + static int freq_offset=0; UE->is_synchronized = 0; if (UE->UE_scan == 0) { - LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu64", UL %"PRIu64" (oai_exit %d, rx_num_channels %d)\n", - UE->frame_parms.dl_CarrierFreq, UE->frame_parms.ul_CarrierFreq, - oai_exit, openair0_cfg[0].rx_num_channels); + + #ifdef FR2_TEST + // Overwrite DL frequency (for FR2 testing) + if (downlink_frequency[0][0]!=0){ + UE->frame_parms.dl_CarrierFreq = downlink_frequency[0][0]; + UE->frame_parms.ul_CarrierFreq = downlink_frequency[0][0]; + } + #endif for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq; - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - if (UE->frame_parms.frame_type == FDD) - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; - else - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %f, UL %f (RF card %d, oai_exit %d, channel %d, rx_num_channels %d)\n", + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i], + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i], + UE->rf_map.card, + oai_exit, + i, + openair0_cfg[0].rx_num_channels); + } sync_mode = pbch; @@ -247,31 +254,25 @@ static void UE_synch(void *arg) { case pbch: LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); + uint64_t dl_carrier, ul_carrier; + double rx_gain_off = 0; + nr_get_carrier_frequencies(&UE->frame_parms, &dl_carrier, &ul_carrier); + if (nr_initial_sync( &syncD->proc, UE, UE->mode,2) == 0) { freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) + round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0); - LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %lu, UL %lu), UE_scan_carrier %d\n", - hw_slot_offset, - freq_offset, - UE->rx_total_gain_dB, - UE->frame_parms.dl_CarrierFreq+freq_offset, - UE->frame_parms.ul_CarrierFreq+freq_offset, - UE->UE_scan_carrier ); // rerun with new cell parameters and frequency-offset - for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + // todo: the freq_offset computed on DL shall be scaled before being applied to UL + nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset); - if (freq_offset >= 0) - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(freq_offset); - else - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(freq_offset); - - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+(UE->frame_parms.ul_CarrierFreq-UE->frame_parms.dl_CarrierFreq); - UE->frame_parms.dl_CarrierFreq = openair0_cfg[CC_id].rx_freq[i]; - } + LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n", + hw_slot_offset, + freq_offset, + openair0_cfg[UE->rf_map.card].rx_gain[0], + openair0_cfg[UE->rf_map.card].rx_freq[0], + openair0_cfg[UE->rf_map.card].tx_freq[0]); // reconfigure for potentially different bandwidth switch(UE->frame_parms.N_RB_DL) { @@ -315,7 +316,6 @@ static void UE_synch(void *arg) { //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); //UE->rfdevice.trx_stop_func(&UE->rfdevice); // sleep(1); - //nr_init_frame_parms_ue(&UE->frame_parms); /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { LOG_E(HW,"Could not start the device\n"); oai_exit=1; @@ -328,31 +328,21 @@ static void UE_synch(void *arg) { UE->is_synchronized = 1; } } else { - // initial sync failed - // calculate new offset and try again + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) freq_offset += 100; freq_offset *= -1; - LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %lu, UL %lu)\n", - freq_offset, - UE->rx_total_gain_dB, - UE->frame_parms.dl_CarrierFreq+freq_offset, - UE->frame_parms.ul_CarrierFreq+freq_offset ); - for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq+freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq+freq_offset; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset); - if (UE->UE_scan_carrier==1) - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } + LOG_I(PHY, "Initial sync failed: trying carrier off %d Hz\n", freq_offset); if (UE->mode != loop_through_memory) UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - }// initial_sync=0 + } break; @@ -365,7 +355,7 @@ static void UE_synch(void *arg) { void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { fapi_nr_config_request_t *cfg = &UE->nrUE_config; - int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_tti_tx); + int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx); uint8_t gNB_id = 0; if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){ @@ -380,16 +370,16 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { ul_indication.gNB_index = gNB_id; ul_indication.cc_id = UE->CC_id; ul_indication.frame_rx = proc->frame_rx; - ul_indication.slot_rx = proc->nr_tti_rx; + ul_indication.slot_rx = proc->nr_slot_rx; ul_indication.frame_tx = proc->frame_tx; - ul_indication.slot_tx = proc->nr_tti_tx; + ul_indication.slot_tx = proc->nr_slot_tx; + ul_indication.thread_id = proc->thread_id; UE->if_inst->ul_indication(&ul_indication); } if (UE->mode != loop_through_memory) { - uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_rx]; - phy_procedures_nrUE_TX(UE,proc,0,thread_id); + phy_procedures_nrUE_TX(UE,proc,0); } } } @@ -397,7 +387,7 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { fapi_nr_config_request_t *cfg = &UE->nrUE_config; - int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_tti_rx); + int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_slot_rx); uint8_t gNB_id = 0; if (rx_slot_type == NR_DOWNLINK_SLOT || rx_slot_type == NR_MIXED_SLOT){ @@ -410,7 +400,8 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { dl_indication.gNB_index = gNB_id; dl_indication.cc_id = UE->CC_id; dl_indication.frame = proc->frame_rx; - dl_indication.slot = proc->nr_tti_rx; + dl_indication.slot = proc->nr_slot_rx; + dl_indication.thread_id = proc->thread_id; UE->if_inst->dl_indication(&dl_indication, NULL); } @@ -421,16 +412,16 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { #else uint64_t a=rdtsc(); phy_procedures_nrUE_RX( UE, proc, 0, UE->mode); - LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500); + LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_slot_rx, (rdtsc()-a)/3500); //printf(">>> nr_ue_pdcch_procedures ended\n"); #endif - if(IS_SOFTMODEM_NOS1){ //&& proc->nr_tti_rx==1 + if(IS_SOFTMODEM_NOS1){ //&& proc->nr_slot_rx==1 //Hardcoded rnti value protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO, 0x1234, proc->frame_rx, - proc->nr_tti_rx, 0); + proc->nr_slot_rx, 0); pdcp_run(&ctxt); } } @@ -445,7 +436,8 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { UE->ul_indication.gNB_index = 0; UE->ul_indication.cc_id = 0; UE->ul_indication.frame = proc->frame_rx; - UE->ul_indication.slot = proc->nr_tti_rx; + UE->ul_indication.slot = proc->nr_slot_rx; + UE->ul_indication.thread_id = proc->thread_id; UE->if_inst->ul_indication(&UE->ul_indication); } } @@ -480,7 +472,7 @@ void UE_processing(void *arg) { if (UE->mac_enabled == 1) { uint8_t gNB_id = 0; NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id]; - int slot_tx = proc->nr_tti_tx; + int slot_tx = proc->nr_slot_tx; int frame_tx = proc->frame_tx; if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) { @@ -698,14 +690,12 @@ void *UE_thread(void *arg) { processingData_t *curMsg=(processingData_t *)NotifiedFifoData(msgToPush); curMsg->UE=UE; // update thread index for received subframe - curMsg->UE->current_thread_id[slot_nr] = thread_idx; - curMsg->proc.CC_id = UE->CC_id; - curMsg->proc.nr_tti_rx= slot_nr; - curMsg->proc.subframe_rx=slot_nr/(nb_slot_frame/10); - curMsg->proc.nr_tti_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame; - curMsg->proc.subframe_tx=curMsg->proc.nr_tti_rx; - curMsg->proc.frame_rx = (absolute_slot/nb_slot_frame) % MAX_FRAME_NUMBER; - curMsg->proc.frame_tx = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER; + curMsg->proc.thread_id = thread_idx; + curMsg->proc.CC_id = UE->CC_id; + curMsg->proc.nr_slot_rx = slot_nr; + curMsg->proc.nr_slot_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame; + curMsg->proc.frame_rx = (absolute_slot/nb_slot_frame) % MAX_FRAME_NUMBER; + curMsg->proc.frame_tx = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER; curMsg->proc.decoded_frame_rx=-1; //LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index e6d644453c..08834ed740 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -40,7 +40,7 @@ //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all #include "openair1/PHY/MODULATION/nr_modulation.h" #include "PHY/phy_vars_nr_ue.h" -#include "PHY/LTE_TRANSPORT/transport_vars.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "SCHED/sched_common_vars.h" #include "PHY/MODULATION/modulation_vars.h" //#include "../../SIMU/USER/init_lte.h" @@ -85,7 +85,9 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "executables/softmodem-common.h" #include "executables/thread-common.h" -// Raphael : missing +extern const char *duplex_mode[]; + +// Thread variables pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex @@ -94,30 +96,40 @@ pthread_cond_t sync_cond; pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. int config_sync_var=-1; +tpool_t *Tpool; +#ifdef UE_DLSCH_PARALLELISATION + tpool_t *Tpool_dl; +#endif RAN_CONTEXT_t RC; volatile int start_eNB = 0; volatile int start_UE = 0; volatile int oai_exit = 0; -int single_thread_flag=1; -static double snr_dB=20; +// Command line options -int threequarter_fs=0; +extern int16_t nr_dlsch_demod_shift; +static int tx_max_power[MAX_NUM_CCs] = {0}; -uint64_t downlink_frequency[MAX_NUM_CCs][4]; -int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; -//int32_t uplink_counter = 0; - - -extern int16_t nr_dlsch_demod_shift; - -int UE_scan = 0; -int UE_scan_carrier = 0; -int UE_fo_compensation = 0; +int single_thread_flag = 1; +int threequarter_fs = 0; +int UE_scan_carrier = 0; +int UE_fo_compensation = 0; int UE_no_timing_correction = 0; -runmode_t mode = normal_txrx; -openair0_config_t openair0_cfg[MAX_CARDS]; +int N_RB_DL = 0; +int tddflag = 0; +int vcdflag = 0; +uint8_t nb_antenna_tx = 1; +uint8_t nb_antenna_rx = 1; +double rx_gain_off = 0.0; +uint32_t timing_advance = 0; +char *usrp_args = NULL; +char *rrc_config_path = NULL; +int dumpframe = 0; + +uint64_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +int rx_input_level_dBm; #if MAX_NUM_CCs == 1 rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}}; @@ -129,74 +141,25 @@ double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}}; double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}}; #endif -double rx_gain_off = 0.0; +// UE and OAI config variables -double sample_rate=30.72e6; -double bw = 10.0e6; +openair0_config_t openair0_cfg[MAX_CARDS]; +int16_t node_synch_ref[MAX_NUM_CCs]; +int otg_enabled; +double cpuf; -static int tx_max_power[MAX_NUM_CCs] = {0}; - - -int chain_offset=0; - - -uint8_t dci_Format = 0; -uint8_t agregation_Level =0xFF; - -uint8_t nb_antenna_tx = 1; -uint8_t nb_antenna_rx = 1; - -char ref[128] = "internal"; -char channels[128] = "0"; - - -int rx_input_level_dBm; - -//static int online_log_messages=0; - - -int otg_enabled; -//int number_of_cards = 1; - -static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; -int16_t node_synch_ref[MAX_NUM_CCs]; - -uint32_t target_dl_mcs = 28; //maximum allowed mcs -uint32_t target_ul_mcs = 20; -uint32_t timing_advance = 0; -uint64_t num_missed_slots=0; // counter for the number of missed slots - - -int transmission_mode=1; -int numerology = 0; -int usrp_tx_thread = 0; - -/* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */ -//uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD; -/* struct for ethernet specific parameters given in eNB conf file */ -//eth_params_t *eth_params; - -double cpuf; +runmode_t mode = normal_txrx; +int UE_scan = 0; +int chain_offset = 0; +uint64_t num_missed_slots = 0; // counter for the number of missed slots +int transmission_mode = 1; +int numerology = 0; +int usrp_tx_thread = 0; +int oaisim_flag = 0; +int emulate_rf = 0; char uecap_xer[1024],uecap_xer_in=0; -int oaisim_flag=0; -int emulate_rf = 0; - -tpool_t *Tpool; -#ifdef UE_DLSCH_PARALLELISATION - tpool_t *Tpool_dl; -#endif - - -char *usrp_args=NULL; - -char *rrc_config_path=NULL; - -/* forward declarations */ -void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); - - /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed * this is very hackish - find a proper solution */ @@ -245,37 +208,6 @@ void exit_function(const char *file, const char *function, const int line, const exit(1); } - -void reset_stats(long arg) { - //int i,j,k; - /*PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0]; - - for (i=0; idlsch[i][0]->Mlimit; j++) { - phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0; - phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0; - phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0; - } - - phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0; - phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0; - phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0; - - for (j=0; julsch[i]->Mlimit; j++) { - phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0; - phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0; - phy_vars_eNB->UE_stats[i].ulsch_round_errors[k][j]=0; - phy_vars_eNB->UE_stats[i].ulsch_round_fer[k][j]=0; - } - } - - phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0; - phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0; - phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0; - }*/ -} - void *l2l1_task(void *arg) { MessageDef *message_p = NULL; int result; @@ -316,21 +248,12 @@ void *l2l1_task(void *arg) { return NULL; } - -int16_t dlsch_demod_shift; - static void get_options(void) { - int CC_id; - int tddflag=0, nonbiotflag, vcdflag=0; + char *loopfile=NULL; - int dumpframe=0; - //uint32_t noS1; - //uint32_t nokrnmod; - //uint32_t nokrnmod; + paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ; config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); - - paramdef_t cmdline_uemodeparams[] = CMDLINE_UEMODEPARAMS_DESC; paramdef_t cmdline_ueparams[] = CMDLINE_NRUEPARAMS_DESC; config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL); @@ -351,54 +274,12 @@ static void get_options(void) { if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; - if (dumpframe > 0) mode = rx_dump_frame; - - for (CC_id=0; CC_iddl_CarrierFreq = downlink_frequency[0][0]; - } - - UE_scan=0; - - if (tddflag > 0) { - for (CC_id=0; CC_idframe_type = TDD; - } + if ((cmdline_uemodeparams[CMDLINE_DUMPMEMORY_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) + mode = rx_dump_frame; if (vcdflag > 0) ouput_vcd = 1; - /*if (frame_parms[0]->N_RB_DL !=0) { - if ( frame_parms[0]->N_RB_DL < 6 ) { - frame_parms[0]->N_RB_DL = 6; - printf ( "%i: Invalid number of resource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL); - } - if ( frame_parms[0]->N_RB_DL > 100 ) { - frame_parms[0]->N_RB_DL = 100; - printf ( "%i: Invalid number of resource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL); - } - if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) { - frame_parms[0]->N_RB_DL = 50; - printf ( "%i: Invalid number of resource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL); - } - if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) { - frame_parms[0]->N_RB_DL = 25; - printf ( "%i: Invalid number of resource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL); - } - UE_scan = 0; - frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL; - for (CC_id=1; CC_idN_RB_DL=frame_parms[0]->N_RB_DL; - frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL; - } - }*/ - - for (CC_id=1; CC_idnr_band = 78; - frame_parms[CC_id]->frame_type = FDD; - frame_parms[CC_id]->tdd_config = 3; - //frame_parms[CC_id]->tdd_config_S = 0; - frame_parms[CC_id]->N_RB_DL = 106; - frame_parms[CC_id]->N_RB_UL = 106; - frame_parms[CC_id]->Ncp = NORMAL; - //frame_parms[CC_id]->Ncp_UL = NORMAL; - frame_parms[CC_id]->Nid_cell = 0; - //frame_parms[CC_id]->num_MBSFN_config = 0; - frame_parms[CC_id]->nb_antenna_ports_gNB = 1; - frame_parms[CC_id]->nb_antennas_tx = 1; - frame_parms[CC_id]->nb_antennas_rx = 1; - //frame_parms[CC_id]->nushift = 0; - // NR: Init to legacy LTE 20Mhz params - frame_parms[CC_id]->numerology_index = 0; - frame_parms[CC_id]->ttis_per_subframe = 1; - frame_parms[CC_id]->slots_per_tti = 2; + // Set UE variables + UE->UE_scan = UE_scan; + UE->UE_scan_carrier = UE_scan_carrier; + UE->UE_fo_compensation = UE_fo_compensation; + UE->no_timing_correction = UE_no_timing_correction; + UE->mode = mode; + UE->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; + UE->tx_total_gain_dB = (int)tx_gain[CC_id][0]; + UE->tx_power_max_dBm = tx_max_power[CC_id]; + + LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan %d, UE_scan_carrier %d, UE_no_timing_correction %d \n", mode, UE_fo_compensation, UE_scan, UE_scan_carrier, UE_no_timing_correction); + + // Set FP variables + NR_DL_FRAME_PARMS *fp = &UE->frame_parms; + fp->nb_antennas_tx = nb_antenna_tx; + fp->nb_antennas_rx = nb_antenna_rx; + fp->threequarter_fs = threequarter_fs; + if (tddflag){ + fp->frame_type = TDD; + LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type); } + if (N_RB_DL){ + fp->N_RB_DL = N_RB_DL; + LOG_I(PHY, "Set UE N_RB_DL %d\n", N_RB_DL); + } + + LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", nb_antenna_rx, nb_antenna_tx, threequarter_fs); + } void init_openair0(void) { int card; - int i; + int freq_off = 0; + NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms; for (card=0; cardthreequarter_fs; - numerology = frame_parms[0]->numerology_index; + openair0_cfg[card].threequarter_fs = frame_parms->threequarter_fs; + numerology = frame_parms->numerology_index; - if(frame_parms[0]->N_RB_DL == 66) { + if(frame_parms->N_RB_DL == 66) { if (numerology==3) { openair0_cfg[card].sample_rate=122.88e6; openair0_cfg[card].samples_per_frame = 1228800; @@ -453,7 +346,7 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n"); exit(-1); } - }else if(frame_parms[0]->N_RB_DL == 32) { + }else if(frame_parms->N_RB_DL == 32) { if (numerology==3) { openair0_cfg[card].sample_rate=61.44e6; openair0_cfg[card].samples_per_frame = 614400; @@ -461,9 +354,9 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n"); exit(-1); } - }else if(frame_parms[0]->N_RB_DL == 217) { + }else if(frame_parms->N_RB_DL == 217) { if (numerology==1) { - if (frame_parms[0]->threequarter_fs) { + if (frame_parms->threequarter_fs) { openair0_cfg[card].sample_rate=92.16e6; openair0_cfg[card].samples_per_frame = 921600; } @@ -475,9 +368,9 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology!\n"); exit(-1); } - } else if(frame_parms[0]->N_RB_DL == 273) { + } else if(frame_parms->N_RB_DL == 273) { if (numerology==1) { - if (frame_parms[0]->threequarter_fs) { + if (frame_parms->threequarter_fs) { AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); } else { @@ -488,9 +381,9 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology!\n"); exit(-1); } - } else if(frame_parms[0]->N_RB_DL == 106) { + } else if(frame_parms->N_RB_DL == 106) { if (numerology==0) { - if (frame_parms[0]->threequarter_fs) { + if (frame_parms->threequarter_fs) { openair0_cfg[card].sample_rate=23.04e6; openair0_cfg[card].samples_per_frame = 230400; } else { @@ -498,7 +391,7 @@ void init_openair0(void) { openair0_cfg[card].samples_per_frame = 307200; } } else if (numerology==1) { - if (frame_parms[0]->threequarter_fs) { + if (frame_parms->threequarter_fs) { openair0_cfg[card].sample_rate=46.08e6; openair0_cfg[card].samples_per_frame = 460800; } @@ -513,57 +406,44 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology!\n"); exit(-1); } - } else if(frame_parms[0]->N_RB_DL == 50) { + } else if(frame_parms->N_RB_DL == 50) { openair0_cfg[card].sample_rate=15.36e6; openair0_cfg[card].samples_per_frame = 153600; - } else if (frame_parms[0]->N_RB_DL == 25) { + } else if (frame_parms->N_RB_DL == 25) { openair0_cfg[card].sample_rate=7.68e6; openair0_cfg[card].samples_per_frame = 76800; - } else if (frame_parms[0]->N_RB_DL == 6) { + } else if (frame_parms->N_RB_DL == 6) { openair0_cfg[card].sample_rate=1.92e6; openair0_cfg[card].samples_per_frame = 19200; } else { - LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms[0]->N_RB_DL); + LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms->N_RB_DL); exit(-1); } - if (frame_parms[0]->frame_type==TDD) + if (frame_parms->frame_type==TDD) openair0_cfg[card].duplex_mode = duplex_mode_TDD; - else //FDD + else openair0_cfg[card].duplex_mode = duplex_mode_FDD; - printf("HW: Configuring card %d, nb_antennas_tx/rx %hhu/%hhu\n",card, - PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx, - PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); openair0_cfg[card].Mod_id = 0; - openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; + openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL; openair0_cfg[card].clock_source = get_softmodem_params()->clock_source; openair0_cfg[card].time_source = get_softmodem_params()->timing_source; - openair0_cfg[card].tx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx); - openair0_cfg[card].rx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); + openair0_cfg[card].tx_num_channels = min(2, frame_parms->nb_antennas_tx); + openair0_cfg[card].rx_num_channels = min(2, frame_parms->nb_antennas_rx); - for (i=0; i<4; i++) { - if (iul_CarrierFreq; - else - openair0_cfg[card].tx_freq[i]=0.0; + LOG_I(PHY, "HW: Configuring card %d, tx/rx num_channels %d/%d, duplex_mode %s\n", + card, + openair0_cfg[card].tx_num_channels, + openair0_cfg[card].rx_num_channels, + duplex_mode[openair0_cfg[card].duplex_mode]); - if (idl_CarrierFreq; - else - openair0_cfg[card].rx_freq[i]=0.0; + nr_get_carrier_frequencies(frame_parms, &dl_carrier, &ul_carrier); - openair0_cfg[card].autocal[i] = 1; - openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; - openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off; - openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; - printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", - card,i, openair0_cfg[card].tx_gain[i], - openair0_cfg[card].rx_gain[i], - openair0_cfg[card].tx_freq[i], - openair0_cfg[card].rx_freq[i]); - } + nr_rf_card_config(&openair0_cfg[card], rx_gain_off, ul_carrier, dl_carrier, freq_off); + + openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; if (usrp_args) openair0_cfg[card].sdr_addrs = usrp_args; @@ -607,14 +487,12 @@ int main( int argc, char **argv ) { } set_softmodem_sighandler(); CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); - set_default_frame_parms(frame_parms); - mode = normal_txrx; memset(openair0_cfg,0,sizeof(openair0_config_t)*MAX_CARDS); memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); // initialize logging logInit(); // get options and fill parameters from configuration file - get_options (); //Command-line options, enb_properties + get_options(); //Command-line options get_common_options(SOFTMODEM_5GUE_BIT ); #if T_TRACER T_Config_Init(); @@ -649,14 +527,6 @@ int main( int argc, char **argv ) { init_NR_UE(1,rrc_config_path); if(IS_SOFTMODEM_NOS1) init_pdcp(); -/* -#ifdef PDCP_USE_NETLINK - netlink_init(); -#if defined(PDCP_USE_NETLINK_QUEUES) - pdcp_netlink_init(); -#endif -#endif -*/ NB_UE_INST=1; NB_INST=1; @@ -667,93 +537,33 @@ int main( int argc, char **argv ) { AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n"); for (int CC_id=0; CC_idofdm_symbol_size); - frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx; - frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; - frame_parms[CC_id]->nb_antenna_ports_gNB = 1; //initial value overwritten by initial sync later - frame_parms[CC_id]->threequarter_fs = threequarter_fs; - LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx); PHY_vars_UE_g[0][CC_id] = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE)); - UE[CC_id] = PHY_vars_UE_g[0][CC_id]; memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE)); + set_options(CC_id, UE[CC_id]); + NR_UE_MAC_INST_t *mac = get_mac_inst(0); if(mac->if_module != NULL && mac->if_module->phy_config_request != NULL) mac->if_module->phy_config_request(&mac->phy_config); fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config; - nr_init_frame_parms_ue(frame_parms[CC_id],nrUE_config,NORMAL); + nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]); + init_symbol_rotation(&UE[CC_id]->frame_parms, UE[CC_id]->frame_parms.dl_CarrierFreq); + init_nr_ue_vars(UE[CC_id], 0, abstraction_flag); + + #ifdef FR2_TEST // Overwrite DL frequency (for FR2 testing) - if (downlink_frequency[0][0]!=0) { + if (downlink_frequency[0][0]!=0){ frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0]; - frame_parms[CC_id]->ul_CarrierFreq = downlink_frequency[0][0]; - } - - init_symbol_rotation(frame_parms[CC_id],frame_parms[CC_id]->dl_CarrierFreq); - init_nr_ue_vars(UE[CC_id],frame_parms[CC_id],0,abstraction_flag); - - UE[CC_id]->mac_enabled = 1; - UE[CC_id]->if_inst = nr_ue_if_module_init(0); - UE[CC_id]->UE_scan = UE_scan; - UE[CC_id]->UE_scan_carrier = UE_scan_carrier; - UE[CC_id]->UE_fo_compensation = UE_fo_compensation; - UE[CC_id]->mode = mode; - UE[CC_id]->no_timing_correction = UE_no_timing_correction; - printf("UE[%d]->mode = %d\n",CC_id,mode); - - UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; - UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; - - if (UE[CC_id]->frame_parms.frame_type == FDD) { - UE[CC_id]->N_TA_offset = 0; - } else { - int N_RB = UE[CC_id]->frame_parms.N_RB_DL; - int N_TA_offset = UE[CC_id]->frame_parms.ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 - double factor=1; - switch (UE[CC_id]->frame_parms.numerology_index) { - case 0: //15 kHz scs - AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n"); - if (N_RB <= 25) factor = .25; // 7.68 Ms/s - else if (N_RB <=50) factor = .5; // 15.36 Ms/s - else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s - else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s - else AssertFatal(1==0,"Too many PRBS for mu=0\n"); - break; - case 1: //30 kHz sc - AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n"); - if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s - else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s - break; - case 2: //60 kHz scs - AssertFatal(1==0,"scs_common should not be 60 kHz\n"); - break; - case 3: //120 kHz scs - AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n"); - break; - case 4: //240 kHz scs - AssertFatal(1==0,"scs_common should not be 60 kHz\n"); - if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s - else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s - else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB); - break; - - if (N_RB == 100) - UE[CC_id]->N_TA_offset = 624; - else if (N_RB == 50) - UE[CC_id]->N_TA_offset = 624/2; - else if (N_RB == 25) - UE[CC_id]->N_TA_offset = 624/4; - } - if (UE[CC_id]->frame_parms.threequarter_fs == 1) factor = factor*.75; - UE[CC_id]->N_TA_offset = (int)(N_TA_offset * factor); - LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", UE[CC_id]->Mod_id, UE[CC_id]->N_TA_offset, factor, UE[CC_id]->frame_parms.ul_CarrierFreq, N_RB); + if (frame_parms[CC_id]->frame_type == TDD) + frame_parms[CC_id]->ul_CarrierFreq = downlink_frequency[0][0]; } + #endif } - // printf("tx_max_power = %d -> amp %d\n",tx_max_power[0],get_tx_amp(tx_max_poHwer,tx_max_power)); init_openair0(); // init UE_PF_PO and mutex lock pthread_mutex_init(&ue_pf_po_mutex, NULL); @@ -764,7 +574,6 @@ int main( int argc, char **argv ) { if(IS_SOFTMODEM_DOFORMS) { load_softscope("nr",PHY_vars_UE_g[0][0]); } - number_of_cards = 1; for(int CC_id=0; CC_idrf_map.card=0; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 418ed54fc6..b2d321ae29 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -48,13 +48,12 @@ {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \ {"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&UE_fo_compensation, defintval:0, TYPE_INT, 0}, \ {"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \ - {"r" , CONFIG_HLP_PRB, 0, iptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT, 0}, \ - {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ + {"r" , CONFIG_HLP_PRB, 0, iptr:&(N_RB_DL), defintval:25, TYPE_UINT, 0}, \ {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0} \ } /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters common to eNodeB and UE */ +/* command line parameters common to gNB and UE */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_PARAMS_DESC_UE { \ @@ -62,22 +61,16 @@ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \ - {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ - {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ - {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ - {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \ {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0}, \ {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \ } - extern int T_port; extern int T_nowait; extern int T_dont_fork; - // In nr-ue.c extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg); extern void fill_ue_band_info(void); @@ -86,7 +79,7 @@ extern void init_NR_UE_threads(int); extern void reset_opp_meas(void); extern void print_opp_meas(void); void *UE_thread(void *arg); -void init_nr_ue_vars(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); +void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id, uint8_t abstraction_flag); extern tpool_t *Tpool; extern tpool_t *Tpool_dl; #endif diff --git a/executables/ocp-gnb.c b/executables/ocp-gnb.c new file mode 100644 index 0000000000..67f68f43e3 --- /dev/null +++ b/executables/ocp-gnb.c @@ -0,0 +1,1010 @@ +/* + * Author: Laurent Thomas, Open Cells Project + * all rights reserved + */ + +#define _GNU_SOURCE +#include +#include "assertions.h" +#include +#include + +#include "PHY/types.h" + +#include "PHY/INIT/phy_init.h" + +#include "PHY/defs_gNB.h" +#include "SCHED/sched_eNB.h" +#include "SCHED_NR/sched_nr.h" +#include "SCHED_NR/fapi_nr_l1.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "../../ARCH/COMMON/common_lib.h" + +#include "PHY/phy_extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" +#include "LAYER2/MAC/mac_proto.h" +#include "RRC/LTE/rrc_extern.h" +#include "PHY_INTERFACE/phy_interface.h" +#include "common/utils/LOG/log_extern.h" +#include "UTIL/OTG/otg_tx.h" +#include "UTIL/OTG/otg_externs.h" +#include "UTIL/MATH/oml.h" +#include "common/utils/LOG/vcd_signal_dumper.h" +#include "UTIL/OPT/opt.h" +#include "enb_config.h" +#include "s1ap_eNB.h" +#include "SIMULATION/ETH_TRANSPORT/proto.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// should be in a shared lib +#include +#include +#include +#include + +// Global vars +#include +#include +#include +#include +volatile int oai_exit; +int single_thread_flag=1; +uint32_t do_forms=0; +unsigned int mmapped_dma=0; +int8_t threequarter_fs=0; + +uint32_t target_dl_mcs = 28; //maximum allowed mcs +uint32_t target_ul_mcs = 20; +int chain_offset=0; +uint16_t sl_ahead=6; +uint16_t sf_ahead=6; +uint32_t timing_advance = 0; +int transmission_mode=1; +int emulate_rf = 0; +int numerology = 0; +int usrp_tx_thread = 0; + + +int config_sync_var=-1; +pthread_mutex_t nfapi_sync_mutex; +pthread_cond_t nfapi_sync_cond; +int nfapi_sync_var=-1; +uint8_t nfapi_mode = NFAPI_MONOLITHIC; // Default to monolithic mode +double cpuf; + + +pthread_cond_t sync_cond; +pthread_mutex_t sync_mutex; +int sync_var=-1; //!< protected by mutex \ref sync_mutex. + + +uint64_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +time_stats_t softmodem_stats_mt; // main thread +time_stats_t softmodem_stats_hw; // hw acquisition +time_stats_t softmodem_stats_rxtx_sf; // total tx time +time_stats_t nfapi_meas; // total tx time +time_stats_t softmodem_stats_rx_sf; // total rx time +// not used but needed for link +openair0_config_t openair0_cfg[MAX_CARDS]; + +AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; +AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; +int flexran_agent_start(mid_t mod_id) { + memset (agent_rrc_xface, 0, sizeof(agent_rrc_xface)); + memset (agent_mac_xface, 0, sizeof(agent_mac_xface)); + return 0; +} +void flexran_agent_slice_update(mid_t module_idP) { +} +int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p) { + return 0; +} +void proto_agent_stop(mod_id_t mod_id) { +} +int split73=0; +void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { + AssertFatal(false, "Must not be called in this context\n"); +} +int stop_L1L2(module_id_t gnb_id) { + AssertFatal(false, "Must not be called in this context\n"); +} +int restart_L1L2(module_id_t gnb_id) { + AssertFatal(false, "Must not be called in this context\n"); +} + +static int wait_for_sync = 0; +static char *itti_dump_file = NULL; +static double snr_dB=20; +static int DEFBANDS[] = {7}; +static int DEFENBS[] = {0}; +static int DEFBFW[] = {0x00007fff}; + +extern double cpuf; + +short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655}; + +static inline int ocp_rxtx(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) { + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; + start_meas(&softmodem_stats_rxtx_sf); + + // ******************************************************************* + + if (nfapi_mode == NFAPI_MODE_PNF) { + // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick + //add_subframe(&frame, &subframe, 4); + //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); + //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe); + start_meas(&nfapi_meas); + oai_subframe_ind(proc->frame_rx, proc->slot_rx); + stop_meas(&nfapi_meas); + /*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus|| + gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs || + gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs || + gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles || + gNB->UL_INFO.cqi_ind.number_of_cqis + ) { + LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n", + NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, + NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, + NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, + NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles, + gNB->UL_INFO.cqi_ind.number_of_cqis, + frame_rx, slot_rx, + frame_tx, slot_tx); + }*/ + } + + /// NR disabling + // **************************************** + // Common RX procedures subframe n + pthread_mutex_lock(&gNB->UL_INFO_mutex); + gNB->UL_INFO.frame = proc->frame_rx; + gNB->UL_INFO.slot = proc->slot_rx; + gNB->UL_INFO.module_id = gNB->Mod_id; + gNB->UL_INFO.CC_id = gNB->CC_id; + gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); + pthread_mutex_unlock(&gNB->UL_INFO_mutex); + // RX processing + int tx_slot_type = nr_slot_select(cfg,proc->frame_tx,proc->slot_tx); + int rx_slot_type = nr_slot_select(cfg,proc->frame_rx,proc->slot_rx); + + if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) { + // Do PRACH RU processing + L1_nr_prach_procedures(gNB,proc->frame_rx,proc->slot_rx); + phy_procedures_gNB_uespec_RX(gNB, proc->frame_rx, proc->slot_rx); + } + + if (oai_exit) return(-1); + + // ***************************************** + // TX processing for subframe n+sf_ahead + // run PHY TX procedures the one after the other for all CCs to avoid race conditions + // (may be relaxed in the future for performance reasons) + // ***************************************** + + if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { + phy_procedures_gNB_TX(gNB, proc->frame_tx,proc->slot_tx, 1); + } + + stop_meas( &softmodem_stats_rxtx_sf ); + LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->slot_rx, proc->frame_tx, proc->slot_tx); + return(0); +} + + +static void *process_stats_thread(void *param) { + PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param; + reset_meas(&gNB->dlsch_encoding_stats); + reset_meas(&gNB->dlsch_scrambling_stats); + reset_meas(&gNB->dlsch_modulation_stats); + + while(!oai_exit) { + sleep(1); + print_meas(&gNB->dlsch_encoding_stats, "pdsch_encoding", NULL, NULL); + print_meas(&gNB->dlsch_scrambling_stats, "pdsch_scrambling", NULL, NULL); + print_meas(&gNB->dlsch_modulation_stats, "pdsch_modulation", NULL, NULL); + } + + return(NULL); +} + +void init_gNB_proc(int inst) { + PHY_VARS_gNB *gNB = RC.gNB[inst]; + gNB_L1_proc_t *proc = &gNB->proc; + gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc; + gNB_L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx; + L1_proc->instance_cnt = -1; + L1_proc_tx->instance_cnt = -1; + L1_proc->instance_cnt_RUs = 0; + L1_proc_tx->instance_cnt_RUs = 0; + proc->instance_cnt_prach = -1; + proc->instance_cnt_asynch_rxtx = -1; + proc->CC_id = 0; + proc->first_rx =1; + proc->first_tx =1; + proc->RU_mask =0; + proc->RU_mask_tx = (1<num_RU)-1; + proc->RU_mask_prach =0; + pthread_mutex_init( &gNB->UL_INFO_mutex, NULL); + gNB->threadPool = (tpool_t *)malloc(sizeof(tpool_t)); + gNB->respDecode = (notifiedFIFO_t *) malloc(sizeof(notifiedFIFO_t)); + char ul_pool[] = "-1,-1"; + initTpool(ul_pool, gNB->threadPool, false); + initNotifiedFIFO(gNB->respDecode); +} + +/// eNB kept in function name for nffapi calls, TO FIX +void init_gNB_phase2(RU_t *ru) { + int inst; + LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst); + + for (inst=0; instnum_RU:%d\n", gNB->num_RU); + phy_init_nr_gNB(gNB,0,0); + RC.gNB[inst]->num_RU=1; + RC.gNB[inst]->RU_list[0]=ru; + //init_precoding_weights(RC.gNB[inst][CC_id]); + } +} + +void init_gNB(int single_thread_flag,int wait_for_sync) { + for (int inst=0; instRCconfig_NR_L1\n"); + PHY_VARS_gNB *gNB= RC.gNB[inst]; + gNB->abstraction_flag = false; + gNB->single_thread_flag = true; + /*nr_polar_init(&gNB->nrPolar_params, + NR_POLAR_PBCH_MESSAGE_TYPE, + NR_POLAR_PBCH_PAYLOAD_BITS, + NR_POLAR_PBCH_AGGREGATION_LEVEL);*/ + LOG_I(PHY,"Registering with MAC interface module\n"); + AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface"); + gNB->if_inst->NR_Schedule_response = nr_schedule_response; + gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; + memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); + memset((void *)&gNB->UL_tti_req,0,sizeof(nfapi_nr_ul_tti_request_t)); + //memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO)); + LOG_I(PHY,"Setting indication lists\n"); + gNB->UL_INFO.rx_ind.pdu_list = gNB->rx_pdu_list; + gNB->UL_INFO.crc_ind.crc_list = gNB->crc_pdu_list; + /*gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list; + gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list; + gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list; + gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/ + gNB->prach_energy_counter = 0; + } + + LOG_I(PHY,"[nr-softmodem.c] gNB structure allocated\n"); +} + + +void stop_gNB(int nb_inst) { +} + +static void get_options(void) { + paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; + config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); + + if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { + memset((void *)&RC,0,sizeof(RC)); + /* Read RC configuration file */ + NRRCConfig(); + printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %hhd\n", RC.nb_nr_inst,RC.nb_nr_L1_inst,RC.nb_RU); + } + + AssertFatal(RC.nb_nr_L1_inst == 1 && RC.nb_RU == 1, "Only one gNB, one RU and one carrier is supported\n"); +} + +void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs], + NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { + for (int CC_id=0; CC_idsubframe_config.numerology_index_mu.value =1; + config[CC_id]->subframe_config.duplex_mode.value = 1; //FDD + config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL + config[CC_id]->rf_config.dl_carrier_bandwidth.value = 106; + config[CC_id]->rf_config.ul_carrier_bandwidth.value = 106; + config[CC_id]->sch_config.physical_cell_id.value = 0; + } +} + +static void init_pdcp(void) { + //if (!NODE_IS_DU(RC.rrc[0]->node_type)) { + pdcp_layer_init(); + uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? + (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; + + if (IS_SOFTMODEM_NOS1) { + printf("IS_SOFTMODEM_NOS1 option enabled \n"); + pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; + } + + pdcp_module_init(pdcp_initmask); + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); +} + +void init_main_gNB(void) { + RCconfig_NR_L1(); + RCconfig_nr_macrlc(); + + if (RC.nb_nr_L1_inst>0) + AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n"); + + LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst); + RC.nrrrc = (gNB_RRC_INST **)calloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *),1); + LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc); + int gnb_id=0; // only 1 gnb per process, index 0 for now + RC.nrrrc[gnb_id] = (gNB_RRC_INST *)calloc(sizeof(gNB_RRC_INST),1); + MessageDef *msg_p = itti_alloc_new_message (TASK_GNB_APP, NRRRC_CONFIGURATION_REQ); + RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]); + openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(ITTI_MSG_INSTANCE(msg_p)), &NRRRC_CONFIGURATION_REQ(msg_p)); + //AssertFatal(itti_create_task(TASK_GNB_APP, gNB_app_task, NULL) >= 0, ""); + AssertFatal(itti_create_task(TASK_RRC_GNB, rrc_gnb_task, NULL) >= 0, ""); + //AssertFatal(itti_create_task(TASK_X2AP, x2ap_task, NULL) >= 0, ""); +} + +static void wait_nfapi_init(char *thread_name) { + printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); + pthread_mutex_lock( &nfapi_sync_mutex ); + + while (nfapi_sync_var<0) + pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex ); + + pthread_mutex_unlock(&nfapi_sync_mutex); + printf( "NFAPI: got sync (%s)\n", thread_name); +} + +void exit_function(const char *file, const char *function, const int line, const char *s) { + if (s != NULL) { + printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); + } + + oai_exit = 1; + sleep(1); //allow lte-softmodem threads to exit first + exit(1); +} + +void stop_RU(int nb_ru) { + return; +} + +void OCPconfig_RU(RU_t *ru) { + int i = 0, j = 0; // Ru and gNB cardinality + paramdef_t RUParams[] = RUPARAMS_DESC; + paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; + config_getlist( &RUParamList, RUParams, sizeof(RUParams)/sizeof(paramdef_t), NULL); + AssertFatal( RUParamList.numelt == 1 && RC.nb_nr_L1_inst ==1,"" ); + ru->idx=0; + ru->nr_frame_parms = (NR_DL_FRAME_PARMS *)calloc(sizeof(NR_DL_FRAME_PARMS),1); + ru->frame_parms = (LTE_DL_FRAME_PARMS *)calloc(sizeof(LTE_DL_FRAME_PARMS),1); + ru->if_timing = synch_to_ext_device; + ru->num_gNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; + ru->gNB_list[i] = &RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; + + if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) { + ru->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr)); + } + + if (config_isparamset(RUParamList.paramarray[j], RU_SDR_CLK_SRC)) { + if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "internal") == 0) { + ru->openair0_cfg.clock_source = internal; + LOG_D(PHY, "RU clock source set as internal\n"); + } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "external") == 0) { + ru->openair0_cfg.clock_source = external; + LOG_D(PHY, "RU clock source set as external\n"); + } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "gpsdo") == 0) { + ru->openair0_cfg.clock_source = gpsdo; + LOG_D(PHY, "RU clock source set as gpsdo\n"); + } else { + LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr)); + } + } else { + ru->openair0_cfg.clock_source = unset; + } + + if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { + if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { + ru->if_south = REMOTE_IF5; //TBD: max value to avoid to call "ru" functions + ru->function = gNodeB_3GPP; + printf("Setting function for RU %d to gNodeB_3GPP\n",j); + } else { + } + + ru->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; + ru->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); + ru->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; + + for (i=0; inum_bands; i++) ru->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; + } //strcmp(local_rf, "yes") == 0 + else { + } + + ru->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); + ru->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); + ru->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); + ru->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); + + if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { + ru->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; + + for (i=0; inum_gNB; i++) { + ru->bw_list[i] = (int32_t *)malloc16_clear((ru->nb_bfw)*sizeof(int32_t)); + + for (int b=0; bnb_bfw; b++) ru->bw_list[i][b] = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].iptr[b]; + } + } + + return; +} + +// this is for RU with local RF unit +void fill_rf_config(RU_t *ru, char *rf_config_file) { + int i; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index + openair0_config_t *cfg = &ru->openair0_cfg; + int mu = gNB_config->ssb_config.scs_common.value; + int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; + fp->threequarter_fs=threequarter_fs; + + if (mu == NR_MU_0) { //or if LTE + if(N_RB == 100) { + if (fp->threequarter_fs) { + cfg->sample_rate=23.04e6; + cfg->samples_per_frame = 230400; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } else { + cfg->sample_rate=30.72e6; + cfg->samples_per_frame = 307200; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + } else if(N_RB == 50) { + cfg->sample_rate=15.36e6; + cfg->samples_per_frame = 153600; + cfg->tx_bw = 5e6; + cfg->rx_bw = 5e6; + } else if (N_RB == 25) { + cfg->sample_rate=7.68e6; + cfg->samples_per_frame = 76800; + cfg->tx_bw = 2.5e6; + cfg->rx_bw = 2.5e6; + } else if (N_RB == 6) { + cfg->sample_rate=1.92e6; + cfg->samples_per_frame = 19200; + cfg->tx_bw = 1.5e6; + cfg->rx_bw = 1.5e6; + } else AssertFatal(1==0,"Unknown N_RB %d\n",N_RB); + } else if (mu == NR_MU_1) { + if(N_RB == 273) { + if (fp->threequarter_fs) { + AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); + } else { + cfg->sample_rate=122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } + } else if(N_RB == 217) { + if (fp->threequarter_fs) { + cfg->sample_rate=92.16e6; + cfg->samples_per_frame = 921600; + cfg->tx_bw = 80e6; + cfg->rx_bw = 80e6; + } else { + cfg->sample_rate=122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 80e6; + cfg->rx_bw = 80e6; + } + } else if(N_RB == 106) { + if (fp->threequarter_fs) { + cfg->sample_rate=46.08e6; + cfg->samples_per_frame = 460800; + cfg->tx_bw = 40e6; + cfg->rx_bw = 40e6; + } else { + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 40e6; + cfg->rx_bw = 40e6; + } + } else { + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); + } + } else if (mu == NR_MU_3) { + if (N_RB == 66) { + cfg->sample_rate = 122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } else if(N_RB == 32) { + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; + } + } else { + AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); + } + + if (gNB_config->cell_config.frame_duplex_type.value==TDD) + cfg->duplex_mode = duplex_mode_TDD; + else //FDD + cfg->duplex_mode = duplex_mode_FDD; + + cfg->Mod_id = 0; + cfg->num_rb_dl=N_RB; + cfg->tx_num_channels=ru->nb_tx; + cfg->rx_num_channels=ru->nb_rx; + + for (i=0; inb_tx; i++) { + if (ru->if_frequency == 0) { + cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; + cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; + } else { + cfg->tx_freq[i] = (double)ru->if_frequency; + cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq); + } + + cfg->tx_gain[i] = ru->att_tx; + cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx; + cfg->configFilename = rf_config_file; + printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", + i, cfg->tx_gain[i], + cfg->rx_gain[i], + cfg->tx_freq[i], + cfg->rx_freq[i]); + } +} + +/* this function maps the RU tx and rx buffers to the available rf chains. + Each rf chain is is addressed by the card number and the chain on the card. The + rf_map specifies for each antenna port, on which rf chain the mapping should start. Multiple + antennas are mapped to successive RF chains on the same card. */ +int setup_RU_buffers(RU_t *ru) { + int i,j; + int card,ant; + //uint16_t N_TA_offset = 0; + NR_DL_FRAME_PARMS *frame_parms; + nfapi_nr_config_request_scf_t *config = &ru->config; + + if (ru) { + frame_parms = ru->nr_frame_parms; + printf("setup_RU_buffers: frame_parms = %p\n",frame_parms); + } else { + printf("ru pointer is NULL\n"); + return(-1); + } + + int mu = config->ssb_config.scs_common.value; + int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; + + if (config->cell_config.frame_duplex_type.value == TDD) { + int N_TA_offset = config->carrier_config.uplink_frequency.value < 6000000 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 + double factor=1; + + switch (mu) { + case 0: //15 kHz scs + AssertFatal(N_TA_offset == 400,"scs_common 15kHz only for FR1\n"); + + if (N_RB <= 25) factor = .25; // 7.68 Ms/s + else if (N_RB <=50) factor = .5; // 15.36 Ms/s + else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s + else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s + else AssertFatal(1==0,"Too many PRBS for mu=0\n"); + + break; + + case 1: //30 kHz sc + AssertFatal(N_TA_offset == 400,"scs_common 30kHz only for FR1\n"); + + if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s + else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s + + break; + + case 2: //60 kHz scs + AssertFatal(1==0,"scs_common should not be 60 kHz\n"); + break; + + case 3: //120 kHz scs + AssertFatal(N_TA_offset == 431,"scs_common 120kHz only for FR2\n"); + break; + + case 4: //240 kHz scs + AssertFatal(1==0,"scs_common should not be 60 kHz\n"); + + if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s + else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s + else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB); + + break; + + if (N_RB == 100) ru->N_TA_offset = 624; + else if (N_RB == 50) ru->N_TA_offset = 624/2; + else if (N_RB == 25) ru->N_TA_offset = 624/4; + } + + if (frame_parms->threequarter_fs == 1) factor = factor*.75; + + ru->N_TA_offset = (int)(N_TA_offset * factor); + LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d)\n",ru->idx,ru->N_TA_offset,factor, + config->carrier_config.uplink_frequency.value, N_RB); + } else ru->N_TA_offset = 0; + + if (ru->openair0_cfg.mmapped_dma == 1) { + // replace RX signal buffers with mmaped HW versions + for (i=0; inb_rx; i++) { + card = i/4; + ant = i%4; + printf("Mapping RU id %u, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); + free(ru->common.rxdata[i]); + ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant]; + printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]); + + for (j=0; j<16; j++) { + printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]); + ru->common.rxdata[i][j] = 16-j; + } + } + + for (i=0; inb_tx; i++) { + card = i/4; + ant = i%4; + printf("Mapping RU id %u, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); + free(ru->common.txdata[i]); + ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant]; + printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]); + + for (j=0; j<16; j++) { + printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]); + ru->common.txdata[i][j] = 16-j; + } + } + } else { // not memory-mapped DMA + //nothing to do, everything already allocated in lte_init + } + + return(0); +} +int rx_rf(int rxBufOffet, int nbSamples, int nb_rx, int32_t **rxdata, openair0_device *rfdevice, openair0_timestamp *HWtimeStamp) { + void *rxp[nb_rx]; + + for (int i=0; itrx_read_func(rfdevice, + HWtimeStamp, + rxp, + nbSamples, + nb_rx); + + if (rxs != nbSamples ) + LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",nbSamples,rxs); + + return rxs; +} + +void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { + RU_proc_t *proc = &ru->proc; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + int i,txsymb; + int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame); + int prevslot_type = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame); + int nextslot_type = nr_slot_select(cfg,frame,(slot+1)%fp->slots_per_frame); + int sf_extension = 0; //sf_extension = ru->sf_extension; + int siglen=fp->get_samples_per_slot(slot,fp); + int flags=1; + + //nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame); + if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT || IS_SOFTMODEM_RFSIM) { + if(slot_type == NR_MIXED_SLOT) { + txsymb = 0; + + for(int symbol_count =0; symbol_counttdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) + txsymb++; + } + + AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb); + + if(slot%(fp->slots_per_subframe/2)) + siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + else + siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + + //+ ru->end_of_burst_delay; + flags=3; // end of burst + } + + if (cfg->cell_config.frame_duplex_type.value == TDD && + slot_type == NR_DOWNLINK_SLOT && + prevslot_type == NR_UPLINK_SLOT) { + flags = 2; // start of burst + } + + if (cfg->cell_config.frame_duplex_type.value == TDD && + slot_type == NR_DOWNLINK_SLOT && + nextslot_type == NR_UPLINK_SLOT) { + flags = 3; // end of burst + } + + if (fp->freq_range==nr_FR2) { + // the beam index is written in bits 8-10 of the flags + // bit 11 enables the gpio programming + int beam=0; + + if (slot==0) beam = 11; //3 for boresight & 8 to enable + + /* + if (slot==0 || slot==40) beam=0&8; + if (slot==10 || slot==50) beam=1&8; + if (slot==20 || slot==60) beam=2&8; + if (slot==30 || slot==70) beam=3&8; + */ + flags |= beam<<8; + } + + void *txp[ru->nb_tx]; + + for (i=0; inb_tx; i++) + txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp,0)-sf_extension]; + + // prepare tx buffer pointers + unsigned int txs = ru->rfdevice.trx_write_func(&ru->rfdevice, + timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, + txp, + siglen+sf_extension, + ru->nb_tx, + flags); + LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %d\n",ru->idx, + (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot); + AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen); + } +} + +static void *ru_thread( void *param ) { + RU_t *ru = (RU_t *)param; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); + nr_dump_frame_parms(fp); + AssertFatal(openair0_device_load(&ru->rfdevice,&ru->openair0_cfg)==0,"Cannot connect to local radio\n"); + AssertFatal(ru->rfdevice.trx_start_func(&ru->rfdevice) == 0,"Could not start the RF device\n"); + int64_t slot=-1; + int64_t nextHWTSshouldBe=0, nextRxTSlogical=0; + // weird globals, used in NR_IF_Module.c + sf_ahead = (uint16_t) ceil((float)6/(0x01<numerology_index)); + sl_ahead = sf_ahead*fp->slots_per_subframe; + + // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices + + while (!oai_exit) { + int nextSlot=(slot+1)%fp->slots_per_frame; + uint32_t samples_per_slot = fp->get_samples_per_slot(nextSlot,fp); + int rxBuffOffset=fp->get_samples_slot_timestamp(nextSlot,fp,0); + AssertFatal(rxBuffOffset + samples_per_slot <= fp->samples_per_frame, "Will read outside allocated buffer\n"); + int samples=fp->get_samples_per_slot(nextSlot,fp); + openair0_timestamp HWtimeStamp=0; //for multi RU + int rxs=rx_rf(rxBuffOffset, + samples, + ru->nb_rx, + ru->common.rxdata, + &ru->rfdevice, + &HWtimeStamp); + LOG_D(PHY,"Reading %d samples for slot %d\n",samples_per_slot,nextSlot); + + if ( HWtimeStamp != nextHWTSshouldBe) + LOG_E(HW,"reading a stream must be continuous, %ld, %ld\n", HWtimeStamp, nextHWTSshouldBe); + + nextHWTSshouldBe=HWtimeStamp+rxs; + ru->proc.timestamp_rx=nextRxTSlogical; + nextRxTSlogical+=samples_per_slot; + int64_t HW_to_logical_RxTSoffset=(int64_t)HWtimeStamp-(int64_t)ru->proc.timestamp_rx; + ru->proc.frame_rx = (ru->proc.timestamp_rx / (fp->samples_per_subframe*10))&1023; + uint32_t idx_sf = ru->proc.timestamp_rx / fp->samples_per_subframe; + float offsetInSubframe=ru->proc.timestamp_rx % fp->samples_per_subframe; + ru->proc.tti_rx = (idx_sf * fp->slots_per_subframe + + lroundf(offsetInSubframe / fp->samples_per_slot0))% + fp->slots_per_frame; + LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", + ru->idx, 0, + (unsigned long long int)ru->proc.timestamp_rx, + (int)ru->ts_offset,ru->proc.frame_rx,ru->proc.tti_rx,ru->proc.tti_tx,fp->slots_per_frame); + int slot_type = nr_slot_select(&ru->gNB_list[0]->gNB_config,ru->proc.frame_rx,ru->proc.tti_rx); + + if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { + nr_fep_full(ru,ru->proc.tti_rx); + + for (int aa=0; aanb_rx; aa++) + memcpy((void *)RC.gNB[0]->common_vars.rxdataF[aa], + (void *)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t)); + + LOG_D(PHY, "rxdataF energy: %d\n", signal_energy(ru->common.rxdataF[0], fp->symbols_per_slot*fp->ofdm_symbol_size)); + } + + gNB_L1_proc_t *gNBproc=&RC.gNB[0][0].proc; + gNB_L1_rxtx_proc_t *L1_proc = &gNBproc->L1_proc; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + gNBproc->timestamp_rx = ru->proc.timestamp_rx; + L1_proc->frame_rx = gNBproc->frame_rx = gNBproc->frame_prach = ru->proc.frame_rx = + (ru->proc.timestamp_rx / (fp->samples_per_subframe*10))&1023; + L1_proc->slot_rx = gNBproc->slot_rx = gNBproc->slot_prach = + ru->proc.tti_rx; // computed before in caller function + L1_proc->timestamp_tx = gNBproc->timestamp_tx = ru->proc.timestamp_tx = + ru->proc.timestamp_rx + + sf_ahead*fp->samples_per_subframe; + L1_proc->frame_tx = gNBproc->frame_tx = ru->proc.frame_tx = + (gNBproc->timestamp_tx / (fp->samples_per_subframe*10))&1023; + L1_proc->slot_tx = ru->proc.tti_tx = + (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; + + if (ocp_rxtx(&RC.gNB[0][0],L1_proc) < 0) + LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",RC.gNB[0][0].Mod_id,RC.gNB[0][0].CC_id); + + // do TX front-end processing if needed (precoding and/or IDFTs) + //ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); + nr_feptx_prec(ru,ru->proc.frame_tx,ru->proc.tti_tx); + // do OFDM with/without TX front-end processing if needed + //ru->feptx_ofdm + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + + if (nr_slot_select(cfg,ru->proc.frame_tx, ru->proc.tti_tx ) != NR_UPLINK_SLOT) { + int aa=0; // antenna 0 hardcoded + NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; + nr_feptx0(ru,ru->proc.tti_tx,0,fp->symbols_per_slot,aa); + int *txdata = &ru->common.txdata[aa][fp->get_samples_slot_timestamp(ru->proc.tti_tx,fp,0)]; + int slot_sizeF = (fp->ofdm_symbol_size)* + ((NFAPI_CP_NORMAL == 1) ? 12 : 14); + LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %ld) %d dB, txp (freq) %d dB\n", + ru->proc.frame_tx,ru->proc.tti_tx,ru->proc.timestamp_tx, + dB_fixed(signal_energy((int32_t *)txdata,fp->get_samples_per_slot(ru->proc.tti_tx,fp))), + dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF))); + } + + // do outgoing fronthaul (south) if needed + tx_rf(ru,ru->proc.frame_tx,ru->proc.tti_tx,ru->proc.timestamp_tx+HW_to_logical_RxTSoffset); + slot++; + } + + printf( "Exiting ru_thread \n"); + ru->rfdevice.trx_end_func(&ru->rfdevice); + static int ru_thread_status = 0; + return &ru_thread_status; +} + +void launch_NR_RU(RU_t *ru, char *rf_config_file) { + LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n", + RC.nb_nr_L1_inst,RC.nb_RU,get_nprocs()); + LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); + + for (int ru_id=0; ru_idrf_config_file = rf_config_file; + ru->idx = ru_id; + ru->ts_offset = 0; + // use gNB_list[0] as a reference for RU frame parameters + // NOTE: multiple CC_id are not handled here yet! + LOG_D(PHY, "%s() RC.ru[%d].num_gNB:%d ru->gNB_list[0]:%p rf_config_file:%s\n", + __FUNCTION__, ru_id, ru->num_gNB, ru->gNB_list[0], ru->rf_config_file); + LOG_E(PHY,"ru->gNB_list ru->num_gNB hardcoded: one RU connected to carrier 0 of gNB 0\n"); + ru->gNB_list[0] = &RC.gNB[0][0]; + ru->num_gNB=1; + LOG_I(PHY,"Copying frame parms from gNB in RC to ru %d and frame_parms in ru\n",ru->idx); + RU_proc_t *proc = &ru->proc; + threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "MainLoop", -1, OAI_PRIORITY_RT_MAX ); + } +} + +void init_eNB_afterRU(void) { + AssertFatal(false,""); +} + +int main( int argc, char **argv ) { + AssertFatal(load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY), + "[SOFTMODEM] Error, configuration module init failed\n"); + logInit(); +#ifndef PACKAGE_VERSION +# define PACKAGE_VERSION "UNKNOWN" +#endif + LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + configure_linux(); + get_options (); + get_common_options(SOFTMODEM_GNB_BIT ); + AssertFatal(!CONFIG_ISFLAGSET(CONFIG_ABORT),"Getting configuration failed\n"); + cpuf=get_cpu_freq_GHz(); + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); + set_taus_seed (0); + init_opt(); + init_pdcp(); + init_main_gNB(); + init_gNB(true, wait_for_sync); + /* Start the agent. If it is turned off in the configuration, it won't start */ + RCconfig_nr_flexran(); + + for (int i = 0; i < RC.nb_nr_L1_inst; i++) { + flexran_agent_start(i); + } + + /* + *nfapi stuff very buggy in 4G, not yet implemented in 5G + */ + // init UE_PF_PO and mutex lock (paging from S1AP) + pthread_mutex_init(&ue_pf_po_mutex, NULL); + printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); + pthread_cond_init(&nfapi_sync_cond,NULL); + pthread_mutex_init(&nfapi_sync_mutex, NULL); + const char *nfapi_mode_str[] = { + "MONOLITHIC", "PNF", "VNF", + }; + AssertFatal(nfapi_mode < 3,""); + printf("NFAPI MODE:%s\n", nfapi_mode_str[nfapi_mode]); + + if (nfapi_mode==NFAPI_MODE_VNF) // VNF + wait_nfapi_init("main?"); + + for (int i=0; iconfigured, "Remain threads to manage\n"); + + printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); + config_sync_var=0; + + if (nfapi_mode==NFAPI_MODE_PNF) { // PNF + wait_nfapi_init("main?"); + } + + printf("wait RUs\n"); + printf("ALL RUs READY!\n"); + printf("RC.nb_RU:%d\n", RC.nb_RU); + // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration) + printf("ALL RUs ready - init gNBs\n"); + LOG_E(PHY,"configuring RU from file, hardcoded one gNB for one RU, one carrier\n"); + RU_t ru= {0}; + OCPconfig_RU(&ru); + ru.nr_frame_parms->threequarter_fs=threequarter_fs; + fill_rf_config(&ru,ru.rf_config_file); + init_gNB_phase2(&ru); + memcpy((void *)ru.nr_frame_parms,&RC.gNB[0][0].frame_parms,sizeof(NR_DL_FRAME_PARMS)); + memcpy((void *)&ru.config,(void *)&RC.gNB[0]->gNB_config,sizeof(ru.config)); + AssertFatal(setup_RU_buffers(&ru)==0,"Inconsistent configuration"); + nr_phy_init_RU(&ru); + init_gNB_proc(0); // only instance 0 (one gNB per process) + + if (RC.nb_RU >0) { + printf("Initializing RU threads\n"); + launch_NR_RU(&ru, get_softmodem_params()->rf_config_file); + } + + if (opp_enabled ==1) { + pthread_t t; + threadCreate(&t, process_stats_thread, + (void *)NULL, "time_meas", -1, OAI_PRIORITY_RT_LOW); + } + + if(IS_SOFTMODEM_DOFORMS) { + scopeParms_t tmp= {&argc, argv, &ru, RC.gNB[0]}; + load_softscope("nr",&tmp); + } + + while(!oai_exit) + sleep(1); + + logClean(); + printf("Bye.\n"); + return 0; +} diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 449d2e0957..feb020154b 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -63,6 +63,7 @@ extern "C" #define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n" #define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" #define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n" +#define CONFIG_HLP_ULF "Set the uplink frequency offset for all component carriers\n" #define CONFIG_HLP_CHOFF "Channel id offset\n" #define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n" #define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n" @@ -123,6 +124,7 @@ extern "C" {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \ {"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \ {"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64, 0}, \ + {"CO" , CONFIG_HLP_ULF, 0, iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT, 0}, \ {"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \ {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ @@ -230,6 +232,7 @@ extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr); #define SOFTMODEM_RTSIGNAL (SIGRTMIN+1) extern void set_softmodem_sighandler(void); extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; +extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; #ifdef __cplusplus } #endif diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 59857659c1..3dfbc2811d 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -720,9 +720,6 @@ int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfa } int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) { - if (RC.ru == 0) { - return -1; - } if (RC.eNB == 0) { return -2; @@ -847,9 +844,6 @@ int pnf_phy_ul_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, n req->ul_config_request_body.srs_present ); - if (RC.ru == 0) { - return -1; - } if (RC.eNB == 0) { return -2; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 10058c441e..87a4d6f6af 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -23,6 +23,7 @@ #include "PHY/impl_defs_nr.h" #define NFAPI_UE_MAX_NUM_CB 8 +#define NFAPI_MAX_NUM_UL_PDU 8 /* typedef unsigned int uint32_t; @@ -155,7 +156,7 @@ typedef struct { uint16_t slot; fapi_nr_tx_config_t tx_config; uint16_t number_of_pdus; - fapi_nr_tx_request_body_t *tx_request_body; + fapi_nr_tx_request_body_t tx_request_body[NFAPI_MAX_NUM_UL_PDU]; } fapi_nr_tx_request_t; /// This struct replaces: @@ -170,6 +171,7 @@ typedef struct { uint8_t prach_format; /// Num RA uint8_t num_ra; + uint8_t prach_slot; uint8_t prach_start_symbol; /// 38.211 (NCS 38.211 6.3.3.1). uint16_t num_cs; @@ -179,6 +181,8 @@ typedef struct { uint8_t restricted_set; /// see TS 38.211 (6.3.3.2). uint16_t freq_msg1; + // When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble + uint8_t ssb_nb_in_ro; // nfapi_nr_ul_beamforming_t beamforming; } fapi_nr_ul_config_prach_pdu; 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 63a1e3c6a8..c254e1a028 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 @@ -1260,7 +1260,7 @@ typedef struct typedef struct { - uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 65535 + uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 255 } nfapi_nr_ul_tti_request_number_of_ue_t; @@ -1541,7 +1541,7 @@ typedef struct }nfapi_nr_uci_pucch_pdu_format_2_3_4_t; typedef enum { - NFAPI_NR_UCI_PDCCH_PDU_TYPE = 0, + NFAPI_NR_UCI_PUSCH_PDU_TYPE = 0, NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE = 1, NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE = 2, } nfapi_nr_uci_pdu_type_e; diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index 555f314429..287cbcd1f4 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -260,7 +260,7 @@ crc6 (unsigned char * inptr, int bitlen) } if (resbit > 0) - crc = (crc << resbit) ^ (crc8Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 24); + crc = (crc << resbit) ^ (crc6Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 24); return crc; } diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 005ede615b..80469f3e81 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -45,8 +45,6 @@ /* extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn); - -extern int32_t get_nr_uldl_offset(int nr_bandP); extern openair0_config_t openair0_cfg[MAX_CARDS]; */ @@ -181,9 +179,27 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, LOG_D(PHY,"Initializing PUSCH DMRS Gold sequence with (%x,%x)\n",Nid_pusch[0],Nid_pusch[1]); nr_gold_pusch(gNB, &Nid_pusch[0]); + //CSI RS init + gNB->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **)); + uint32_t ***csi_rs = gNB->nr_gold_csi_rs; + AssertFatal(csi_rs!=NULL, "NR init: csi reference signal malloc failed\n"); + + for (int slot=0; slotslots_per_frame; slot++) { + csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *)); + AssertFatal(csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); + + for (int symb=0; symbsymbols_per_slot; symb++) { + csi_rs[slot][symb] = (uint32_t *)malloc16(NR_MAX_CSI_RS_INIT_LENGTH_DWORD*sizeof(uint32_t)); + AssertFatal(csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); + } + } + + nr_init_csi_rs(gNB, 0); // TODO scramblingID currently hardcoded to 0, to be taken from higher layer parameter scramblingID when implemented + /// Transport init necessary for NR synchro init_nr_transport(gNB); + gNB->first_run_I0_measurements = 1; common_vars->rxdata = (int32_t **)malloc16(Prx*sizeof(int32_t*)); @@ -433,52 +449,26 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { uint8_t short_sequence, num_sequences, rootSequenceIndex, fd_occasion; NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms; nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config; + int32_t dlul_offset = 0; - /* - gNB_config->cell_config.phy_cell_id.value = phy_config->cfg->cell_config.phy_cell_id.value; - gNB_config->carrier_config.dl_frequency.value = phy_config->cfg->carrier_config.dl_frequency.value; - gNB_config->carrier_config.uplink_frequency.value = phy_config->cfg->carrier_config.uplink_frequency.value; - gNB_config->ssb_config.scs_common.value = phy_config->cfg->ssb_config.scs_common.value; - gNB_config->carrier_config.dl_bandwidth.value = phy_config->cfg->carrier_config.dl_bandwidth.value; - gNB_config->carrier_config.uplink_bandwidth.value = phy_config->cfg->carrier_config.uplink_bandwidth.value; - gNB_config->ssb_table.ssb_subcarrier_offset.value = phy_config->cfg->ssb_table.ssb_subcarrier_offset.value; - gNB_config->ssb_table.ssb_offset_point_a.value = phy_config->cfg->ssb_table.ssb_offset_point_a.value; - gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = phy_config->cfg->ssb_table.ssb_mask_list[0].ssb_mask.value; - gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = phy_config->cfg->ssb_table.ssb_mask_list[1].ssb_mask.value; - gNB_config->ssb_table.ssb_period.value = phy_config->cfg->ssb_table.ssb_period.value; - for (int i=0; i<5; i++) { - gNB_config->carrier_config.dl_grid_size[i].value = phy_config->cfg->carrier_config.dl_grid_size[i].value; - gNB_config->carrier_config.ul_grid_size[i].value = phy_config->cfg->carrier_config.ul_grid_size[i].value; - gNB_config->carrier_config.dl_k0[i].value = phy_config->cfg->carrier_config.dl_k0[i].value; - gNB_config->carrier_config.ul_k0[i].value = phy_config->cfg->carrier_config.ul_k0[i].value; - } - - - if (phy_config->cfg->cell_config.frame_duplex_type.value == 0) { - gNB_config->cell_config.frame_duplex_type.value = FDD; - } else { - gNB_config->cell_config.frame_duplex_type.value = TDD; - } - - memcpy((void*)&gNB_config->prach_config,(void*)&phy_config->cfg->prach_config,sizeof(phy_config->cfg->prach_config)); - memcpy((void*)&gNB_config->tdd_table,(void*)&phy_config->cfg->tdd_table,sizeof(phy_config->cfg->tdd_table)); - */ memcpy((void*)gNB_config,phy_config->cfg,sizeof(*phy_config->cfg)); RC.gNB[Mod_id]->mac_enabled = 1; uint64_t dl_bw_khz = (12*gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<ssb_config.scs_common.value); fp->dl_CarrierFreq = ((dl_bw_khz>>1) + gNB_config->carrier_config.dl_frequency.value)*1000 ; - - int32_t dlul_offset = 0; - lte_frame_type_t frame_type = 0; - get_band(fp->dl_CarrierFreq,&fp->nr_band,&dlul_offset,&frame_type); - uint64_t ul_bw_khz = (12*gNB_config->carrier_config.ul_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<ssb_config.scs_common.value); fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ; - AssertFatal(fp->ul_CarrierFreq==(fp->dl_CarrierFreq+dlul_offset), "Disagreement in uplink frequency for band %d\n", fp->nr_band); + fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + + get_delta_duplex(fp->nr_band, gNB_config->ssb_config.scs_common.value, &dlul_offset); + dlul_offset *= 1000; + + AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + dlul_offset), "Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n", fp->nr_band, fp->ul_CarrierFreq, fp->dl_CarrierFreq + dlul_offset); + LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, dlul_offset); + fp->threequarter_fs = openair0_cfg[0].threequarter_fs; LOG_I(PHY,"Configuring MIB for instance %d, : (Nid_cell %d,DL freq %llu, UL freq %llu)\n", Mod_id, diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 39e99e6ec3..24e41d7bfb 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -350,13 +350,6 @@ void phy_config_meas_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n } */ -#if defined(Rel10) || defined(Rel14) -void phy_config_dedicated_scell_ue(uint8_t Mod_id, - uint8_t eNB_index, - SCellToAddMod_r10_t *sCellToAddMod_r10, - int CC_id) { -} -#endif #if 0 void phy_config_harq_ue(module_id_t Mod_id, @@ -374,210 +367,6 @@ void phy_config_harq_ue(module_id_t Mod_id, extern uint16_t beta_cqi[16]; -/* -void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id, - struct PhysicalConfigDedicated *physicalConfigDedicated ) -{ - - static uint8_t first_dedicated_configuration = 0; - PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; - - phy_vars_ue->total_TBS[eNB_id]=0; - phy_vars_ue->total_TBS_last[eNB_id]=0; - phy_vars_ue->bitrate[eNB_id]=0; - phy_vars_ue->total_received_bits[eNB_id]=0; - phy_vars_ue->dlsch_errors[eNB_id]=0; - phy_vars_ue->dlsch_errors_last[eNB_id]=0; - phy_vars_ue->dlsch_received[eNB_id]=0; - phy_vars_ue->dlsch_received_last[eNB_id]=0; - phy_vars_ue->dlsch_fer[eNB_id]=0; - - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; - - if (physicalConfigDedicated) { - LOG_D(PHY,"[UE %d] Received physicalConfigDedicated from eNB %d\n",Mod_id, eNB_id); - LOG_D(PHY,"------------------------------------------------------------------------\n"); - - if (physicalConfigDedicated->pdsch_ConfigDedicated) { - phy_vars_ue->pdsch_config_dedicated[eNB_id].p_a=physicalConfigDedicated->pdsch_ConfigDedicated->p_a; - LOG_D(PHY,"pdsch_config_dedicated.p_a %d\n",phy_vars_ue->pdsch_config_dedicated[eNB_id].p_a); - LOG_D(PHY,"\n"); - } - - if (physicalConfigDedicated->pucch_ConfigDedicated) { - if (physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.present==PUCCH_ConfigDedicated__ackNackRepetition_PR_release) - phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=0; - else { - phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=1; - } - - if (physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode) - phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode = *physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode; - else - phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode = bundling; - - if ( phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode == multiplexing) - LOG_D(PHY,"pucch_config_dedicated.tdd_AckNackFeedbackMode = multiplexing\n"); - else - LOG_D(PHY,"pucch_config_dedicated.tdd_AckNackFeedbackMode = bundling\n"); - } - - if (physicalConfigDedicated->pusch_ConfigDedicated) { - phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; - phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; - phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; - - - LOG_D(PHY,"pusch_config_dedicated.betaOffset_ACK_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index); - LOG_D(PHY,"pusch_config_dedicated.betaOffset_RI_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index); - LOG_D(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d => %d)\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index,beta_cqi[phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index]); - LOG_D(PHY,"\n"); - - - } - - if (physicalConfigDedicated->uplinkPowerControlDedicated) { - - phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH = physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUSCH; - phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled= physicalConfigDedicated->uplinkPowerControlDedicated->deltaMCS_Enabled; - phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled= physicalConfigDedicated->uplinkPowerControlDedicated->accumulationEnabled; - phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUCCH= physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUCCH; - phy_vars_ue->ul_power_control_dedicated[eNB_id].pSRS_Offset= physicalConfigDedicated->uplinkPowerControlDedicated->pSRS_Offset; - phy_vars_ue->ul_power_control_dedicated[eNB_id].filterCoefficient= *physicalConfigDedicated->uplinkPowerControlDedicated->filterCoefficient; - LOG_D(PHY,"ul_power_control_dedicated.p0_UE_PUSCH %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH); - LOG_D(PHY,"ul_power_control_dedicated.deltaMCS_Enabled %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled); - LOG_D(PHY,"ul_power_control_dedicated.accumulationEnabled %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled); - LOG_D(PHY,"ul_power_control_dedicated.p0_UE_PUCCH %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUCCH); - LOG_D(PHY,"ul_power_control_dedicated.pSRS_Offset %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].pSRS_Offset); - LOG_D(PHY,"ul_power_control_dedicated.filterCoefficient %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].filterCoefficient); - LOG_D(PHY,"\n"); - } - - if (physicalConfigDedicated->antennaInfo) { - phy_vars_ue->transmission_mode[eNB_id] = 1+(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); - LOG_I(PHY,"Transmission Mode %d\n",phy_vars_ue->transmission_mode[eNB_id]); - switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { - case AntennaInfoDedicated__transmissionMode_tm1: - phy_vars_ue->transmission_mode[eNB_id] = 1; - break; - case AntennaInfoDedicated__transmissionMode_tm2: - phy_vars_ue->transmission_mode[eNB_id] = 2; - break; - case AntennaInfoDedicated__transmissionMode_tm3: - phy_vars_ue->transmission_mode[eNB_id] = 3; - break; - case AntennaInfoDedicated__transmissionMode_tm4: - phy_vars_ue->transmission_mode[eNB_id] = 4; - break; - case AntennaInfoDedicated__transmissionMode_tm5: - phy_vars_ue->transmission_mode[eNB_id] = 5; - break; - case AntennaInfoDedicated__transmissionMode_tm6: - phy_vars_ue->transmission_mode[eNB_id] = 6; - break; - case AntennaInfoDedicated__transmissionMode_tm7: - lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[0][eNB_id]->crnti); - phy_vars_ue->transmission_mode[eNB_id] = 7; - break; - default: - LOG_E(PHY,"Unknown transmission mode!\n"); - break; - } - } else { - LOG_D(PHY,"[UE %d] Received NULL physicalConfigDedicated->antennaInfo from eNB %d\n",Mod_id, eNB_id); - } - - if (physicalConfigDedicated->schedulingRequestConfig) { - if (physicalConfigDedicated->schedulingRequestConfig->present == SchedulingRequestConfig_PR_setup) { - phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex = physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; - phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex=physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_ConfigIndex; - phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax=physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax; - - LOG_D(PHY,"scheduling_request_config.sr_PUCCH_ResourceIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); - LOG_D(PHY,"scheduling_request_config.sr_ConfigIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex); - LOG_D(PHY,"scheduling_request_config.dsr_TransMax %d\n",phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax); - } - - LOG_D(PHY,"------------------------------------------------------------\n"); - - } - - if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) { - - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 0; - if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 1; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].duration = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].cyclicShift = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_HoppingBandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; - - - LOG_D(PHY,"soundingrs_ul_config_dedicated.srs_ConfigIndex %d\n",phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex); - } - - LOG_D(PHY,"------------------------------------------------------------\n"); - - } - - - if (physicalConfigDedicated->cqi_ReportConfig) { - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) { - // configure PUSCH CQI reporting - phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; - if ((phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm12) && - (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm30) && - (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm31)) - LOG_E(PHY,"Unsupported Aperiodic CQI Feedback Mode : %d\n",phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic); - } - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) { - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) { - // configure PUCCH CQI reporting - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex; - } - else if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_release) { - // handle release - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; - } - } - } - - } else { - LOG_D(PHY,"[PHY][UE %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id,eNB_id); - return; - } - - // fill cqi parameters for periodic CQI reporting - get_cqipmiri_params(phy_vars_ue,eNB_id); - - // disable MIB SIB decoding once we are on connected mode - first_dedicated_configuration ++; - if(first_dedicated_configuration > 1) - { - LOG_I(PHY,"Disable SIB MIB decoding \n"); - phy_vars_ue->decode_SIB = 0; - phy_vars_ue->decode_MIB = 0; - } - //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; - if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234) - phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; - else - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; - - LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti, - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); - - -}*/ - /*! \brief Helper function to allocate memory for DLSCH data structures. * \param[out] pdsch Pointer to the LTE_UE_PDSCH structure to initialize. * \param[in] frame_parms LTE_DL_FRAME_PARMS structure. @@ -656,7 +445,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, fp->nb_antennas_rx=1; // dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig; // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig; - printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx); + LOG_I(PHY, "Initializing UE vars (abstraction %u) for gNB TXant %u, UE RXant %u\n", abstraction_flag, fp->nb_antennas_tx, fp->nb_antennas_rx); //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST); phy_init_nr_top(ue); // many memory allocation sizes are hard coded @@ -969,6 +758,64 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue, //ue->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1; ue->dlsch_MCH[0] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL,0); + + for(int i=0; i<5; i++) + ue->dl_stats[i] = 0; +} + + +void init_N_TA_offset(PHY_VARS_NR_UE *ue){ + + NR_DL_FRAME_PARMS *fp = &ue->frame_parms; + + if (fp->frame_type == FDD) { + ue->N_TA_offset = 0; + } else { + int N_RB = fp->N_RB_DL; + int N_TA_offset = fp->ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 + double factor = 1; + switch (fp->numerology_index) { + case 0: //15 kHz scs + AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n"); + if (N_RB <= 25) factor = .25; // 7.68 Ms/s + else if (N_RB <=50) factor = .5; // 15.36 Ms/s + else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s + else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s + else AssertFatal(1==0, "Too many PRBS for mu=0\n"); + break; + case 1: //30 kHz sc + AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n"); + if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s + else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s + break; + case 2: //60 kHz scs + AssertFatal(1==0, "scs_common should not be 60 kHz\n"); + break; + case 3: //120 kHz scs + AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n"); + break; + case 4: //240 kHz scs + AssertFatal(1==0, "scs_common should not be 60 kHz\n"); + if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s + else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s + else AssertFatal(1==0, "N_RB %d is too big for curretn FR2 implementation\n", N_RB); + break; + + if (N_RB == 100) + ue->N_TA_offset = 624; + else if (N_RB == 50) + ue->N_TA_offset = 624/2; + else if (N_RB == 25) + ue->N_TA_offset = 624/4; + } + + if (fp->threequarter_fs == 1) + factor = factor*.75; + + ue->N_TA_offset = (int)(N_TA_offset * factor); + + LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, N_RB); + } } void phy_init_nr_top(PHY_VARS_NR_UE *ue) { @@ -988,57 +835,3 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue) { //init_scrambling_lut(); //set_taus_seed(1328); } - -void set_default_frame_parms_single(nfapi_nr_config_request_t *config, - NR_DL_FRAME_PARMS *frame_parms) { - /* Set some default values that may be overwritten while reading options */ - frame_parms = (NR_DL_FRAME_PARMS*) malloc(sizeof(NR_DL_FRAME_PARMS)); - config = (nfapi_nr_config_request_t*) malloc(sizeof(nfapi_nr_config_request_t)); - config->subframe_config.numerology_index_mu.value =1; - config->subframe_config.duplex_mode.value = 1; //FDD - config->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL - config->rf_config.dl_carrier_bandwidth.value = 100; - config->rf_config.ul_carrier_bandwidth.value = 100; - config->sch_config.physical_cell_id.value = 0; - - frame_parms->frame_type = FDD; - //frame_parms[CC_id]->tdd_config_S = 0; - frame_parms->N_RB_DL = 106; - frame_parms->N_RB_UL = 106; - frame_parms->Ncp = NORMAL; - //frame_parms[CC_id]->Ncp_UL = NORMAL; - frame_parms->Nid_cell = 0; - //frame_parms[CC_id]->num_MBSFN_config = 0; - frame_parms->nb_antenna_ports_gNB = 1; - frame_parms->nb_antennas_tx = 1; - frame_parms->nb_antennas_rx = 1; - - //frame_parms[CC_id]->nushift = 0; - - ///frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth; - //frame_parms[CC_id]->phich_config_common.phich_duration = normal; - - // UL RS Config - /*frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 1;//n_DMRS1 set to 0 - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; - - frame_parms[CC_id]->pusch_config_common.n_SB = 1; - frame_parms[CC_id]->pusch_config_common.hoppingMode = 0; - frame_parms[CC_id]->pusch_config_common.pusch_HoppingOffset = 0; - frame_parms[CC_id]->pusch_config_common.enable64QAM = 0; - - frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;*/ - - // NR: Init to legacy LTE 20Mhz params - frame_parms->numerology_index = 0; - frame_parms->ttis_per_subframe = 1; - frame_parms->slots_per_tti = 2; - - -} diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 6045930b17..171980d343 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -27,8 +27,6 @@ uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16}; - - int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp) { @@ -85,6 +83,7 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp) void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) { + switch(mu) { case NR_MU_0: //15kHz scs @@ -233,6 +232,20 @@ uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp) return samp_count; } + +uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, NR_DL_FRAME_PARMS* fp) +{ + uint32_t slot_idx = 0; + int samples_till_the_slot = 0; + timestamp_rx = timestamp_rx%fp->samples_per_frame; + + while (timestamp_rx > samples_till_the_slot) { + samples_till_the_slot += fp->get_samples_per_slot(slot_idx,fp); + slot_idx++; + } + return slot_idx; +} + uint32_t get_samples_slot_timestamp(int slot, NR_DL_FRAME_PARMS* fp, uint8_t sl_ahead) { uint32_t samp_count = 0; @@ -251,13 +264,15 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS *fp) { + AssertFatal (cfg != NULL, "%s %s:%i Null pointer to cfg %p!\n", __FUNCTION__, __FILE__, __LINE__, cfg); + fp->frame_type = cfg->cell_config.frame_duplex_type.value; fp->L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ; fp->N_RB_DL = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value; fp->N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; int Ncp = NFAPI_CP_NORMAL; - int mu = cfg!= NULL ? cfg->ssb_config.scs_common.value : 0; + int mu = cfg->ssb_config.scs_common.value; #if DISABLE_LOG_X printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, fp->N_RB_DL, Ncp); @@ -275,9 +290,9 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, fp->slots_per_frame = 10* fp->slots_per_subframe; - fp->nb_antenna_ports_gNB = 1; // default value until overwritten by RRCConnectionReconfiguration - fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration - fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration + fp->nb_antenna_ports_gNB = cfg->carrier_config.num_tx_ant.value;// It corresponds to pdsch_AntennaPorts + fp->nb_antennas_rx = cfg->carrier_config.num_rx_ant.value; // It denotes the number of rx antennas at gNB + fp->nb_antennas_tx = 1; // It corresponds to the number of UE Tx antennas fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; @@ -289,6 +304,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, (fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2); fp->get_samples_per_slot = &get_samples_per_slot; fp->get_samples_slot_timestamp = &get_samples_slot_timestamp; + fp->get_slot_from_timestamp = &get_slot_from_timestamp; fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; @@ -305,7 +321,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, } fp->N_ssb = 0; - int num_tx_ant = (cfg == NULL) ? fp->Lmax : cfg->carrier_config.num_tx_ant.value; + int num_tx_ant = cfg->carrier_config.num_tx_ant.value; for (int p=0; pN_ssb += ((fp->L_ssb >> (63-p)) & 0x01); @@ -315,10 +331,23 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, } int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, - fapi_nr_config_request_t* config, - int Ncp) + fapi_nr_config_request_t* config, + uint16_t nr_band) { + uint8_t nb_ant_ports_gNB = 1; + uint8_t tdd_cfg = 3; + uint8_t Nid_cell = 0; + int Ncp = NORMAL; + + // default values until overwritten by RRCConnectionReconfiguration + fp->nb_antenna_ports_gNB = nb_ant_ports_gNB; + fp->tdd_config = tdd_cfg; + fp->Nid_cell = Nid_cell; + fp->nr_band = nr_band; + + LOG_I(PHY, "Initializing frame parms: set nb_antenna_ports_gNB %d, tdd_config, %d, Nid_cell %d\n", fp->nb_antenna_ports_gNB, fp->tdd_config, fp->Nid_cell); + uint64_t dl_bw_khz = (12*config->carrier_config.dl_grid_size[config->ssb_config.scs_common])*(15<ssb_config.scs_common); fp->dl_CarrierFreq = ((dl_bw_khz>>1) + config->carrier_config.dl_frequency)*1000 ; @@ -330,11 +359,15 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index]; int32_t uplink_frequency_offset = 0; + get_delta_duplex(fp->nr_band, fp->numerology_index, &uplink_frequency_offset); + get_frame_type(fp->nr_band, fp->numerology_index, &fp->frame_type); + uplink_frequency_offset *= 1000; - get_band(fp->dl_CarrierFreq, &fp->nr_band, &uplink_frequency_offset, &fp->frame_type); + LOG_I(PHY, "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, uplink_frequency_offset); AssertFatal(fp->frame_type==config->cell_config.frame_duplex_type, "Invalid duplex type in config request file for band %d\n", fp->nr_band); - AssertFatal(fp->ul_CarrierFreq==(fp->dl_CarrierFreq+uplink_frequency_offset), "Disagreement in uplink frequency for band %d\n", fp->nr_band); + + AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + uplink_frequency_offset), "Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n", fp->nr_band, fp->ul_CarrierFreq, fp->dl_CarrierFreq + uplink_frequency_offset); #if DISABLE_LOG_X printf("Initializing UE frame parms for mu %d, N_RB %d, Ncp %d\n",fp->numerology_index, fp->N_RB_DL, Ncp); @@ -350,11 +383,6 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, set_scs_parameters(fp,fp->numerology_index,config->carrier_config.dl_bandwidth); fp->slots_per_frame = 10* fp->slots_per_subframe; - - fp->nb_antenna_ports_gNB = 1; // default value until overwritten by RRCConnectionReconfiguration - fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration - fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration - fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; @@ -385,7 +413,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->Lmax = 64; } - fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[1].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask; + fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[0].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask; fp->N_ssb = 0; for (int p=0; pLmax; p++) diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index 1862d5f8e0..9c474264c8 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -394,9 +394,10 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp); int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); -int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,fapi_nr_config_request_t *config,int Ncp); +int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band); int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag); void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag); +void init_N_TA_offset(PHY_VARS_NR_UE *ue); void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms); int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char abstraction_flag); void nr_phy_config_request(NR_PHY_Config_t *gNB); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 8c07421b7e..347fbb026b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2242,16 +2242,12 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, MIMO_mode_t mimo_mode = -1; uint8_t mprime=0,Ns; int8_t lprime=-1; - int aa=0; #ifdef DEBUG_DLSCH_MODULATION uint8_t Nl0; //= dlsch0_harq->Nl; uint8_t Nl1; #endif - int ru_id; - RU_t *ru; - int eNB_id; if ((dlsch0 != NULL) && (dlsch1 != NULL)){ @@ -2432,11 +2428,13 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, } // mapping ue specific beamforming weights from UE specified DLSCH structure to RU beam weights for the eNB - for (ru_id=0;ru_idnum_eNB;eNB_id++){ + for (int eNB_id=0;eNB_idnum_eNB;eNB_id++){ if (phy_vars_eNB == ru->eNB_list[eNB_id]) { - for (aa=0;aanb_tx;aa++){ + for (int aa=0;aanb_tx;aa++){ LOG_I(PHY,"ru_id:%d eNB_id:%d aa:%d memcpy(ru->beam_weights, dlsch0->ue_spec_bf_weights[ru_id][0],)\n", ru_id, eNB_id, aa); memcpy(ru->beam_weights[eNB_id][5][aa], dlsch0->ue_spec_bf_weights[ru_id][0], @@ -2445,6 +2443,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, } } } + */ } diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h index 228299095f..72a1334fe9 100644 --- a/openair1/PHY/MODULATION/modulation_UE.h +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -49,12 +49,14 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue, int reset_freq_est); int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue, - unsigned char l, - unsigned char Ns, - int sample_offset, - int no_prefix); + UE_nr_rxtx_proc_t *proc, + unsigned char l, + unsigned char Ns, + int sample_offset, + int no_prefix); int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, unsigned char symbol, unsigned char Ns, int sample_offset, diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 652421f77c..0a7088ba39 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -506,10 +506,10 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq) { const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10; const double Tc=(1/480e3/4096); - const double Nu=2048*64*.5; + const double Nu=2048*64*(1/(float)(1<numerology_index)); const double f0= (double)CarrierFreq; - const double Ncp0=16*64 + (144*64*.5); - const double Ncp1=(144*64*.5); + const double Ncp0=16*64 + (144*64*(1/(float)(1<numerology_index))); + const double Ncp1=(144*64*(1/(float)(1<numerology_index))); double tl=0,poff,exp_re,exp_im; double Ncp,Ncpm1=Ncp0; diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 31d8754768..3d2be905ac 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -112,4 +112,10 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq); +void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, + int32_t *rxdataF, + int slot, + int first_symbol, + int nsymb, + int length); #endif diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 2ffdb013a5..60b28d4ad1 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -37,6 +37,7 @@ #endif*/ int nr_slot_fep(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, unsigned char symbol, unsigned char Ns, int sample_offset, @@ -125,7 +126,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, } for (aa=0; aanb_antennas_rx; aa++) { - memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); + memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); rx_offset = sample_offset + slot_offset - SOFFSET; // Align with 256 bit @@ -157,14 +158,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, (void *) &common_vars->rxdata[aa][rx_offset % frame_length_samples], frame_parms->ofdm_symbol_size*sizeof(int)); dft(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly #if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); #endif dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); #endif @@ -185,11 +186,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, (void *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], frame_parms->ofdm_symbol_size*sizeof(int)); dft(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); @@ -206,9 +207,9 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset]; ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; - rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], (int16_t*)&rot2, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], frame_parms->ofdm_symbol_size, 15); @@ -222,6 +223,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, } int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, unsigned char symbol, unsigned char Ns, int sample_offset, @@ -310,7 +312,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, } for (aa=0; aanb_antennas_rx; aa++) { - memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); + memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); rx_offset = sample_offset + slot_offset - SOFFSET; // Align with 256 bit @@ -342,7 +344,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, (void *) &common_vars->rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size*sizeof(int)); dft(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly #if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); @@ -350,7 +352,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); #endif @@ -371,10 +373,10 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, (void *) &common_vars->rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size*sizeof(int)); dft(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); @@ -393,9 +395,9 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); #endif - rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], (int16_t*)&rot2, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], frame_parms->ofdm_symbol_size, 15); @@ -483,21 +485,41 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, dft(dftsize,(int16_t *)&tmp_dft_in, (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); } - else - dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset], + else { + //dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset], + // (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); + memcpy((void *)tmp_dft_in, + (void *) &rxdata[rxdata_offset-sample_offset], + (frame_parms->ofdm_symbol_size)*sizeof(int)); + dft(dftsize,(int16_t *)&tmp_dft_in, (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); + } // clear DC carrier from OFDM symbols rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0; - int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset]; - ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; - LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",Ns,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); - rotate_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], - (int16_t*)&rot2, - (int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], - frame_parms->ofdm_symbol_size, - 15); return(0); } + +void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, + int32_t *rxdataF, + int slot, + int first_symbol, + int nsymb, + int length) { + + + int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; + + for (int symbol=0;symbolsymbol_rotation)[symbol+symb_offset]; + ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; + LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); + rotate_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], + (int16_t*)&rot2, + (int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], + length, + 15); + } +} diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c index 415e6adfa2..72cb60003e 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.c +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c @@ -37,6 +37,7 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k, uint16_t start_sc, + uint16_t ofdm_symbol_size, uint8_t numDmrsCdmGrpsNoData, uint8_t dmrs_type) { uint8_t delta; @@ -44,7 +45,7 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k, if (k>start_sc) diff = k-start_sc; else - diff = start_sc-k; + diff = (ofdm_symbol_size-start_sc)+k; for (int i = 0; idmrs_DownlinkConfig.pdsch_dmrs_type; - wf = (config_type==0) ? wf1 : wf2; - wt = (config_type==0) ? wt1 : wt2; + wf = (config_type==pdsch_dmrs_type1) ? wf1 : wf2; + wt = (config_type==pdsch_dmrs_type1) ? wt1 : wt2; if (config_type > 1) LOG_E(PHY,"Bad PDSCH DMRS config type %d\n", config_type); - if ((p>=1000) && (p<((config_type==0) ? 1008 : 1012))) { + if ((p>=1000) && (p<((config_type==pdsch_dmrs_type1) ? 1008 : 1012))) { if (ue->frame_parms.Ncp == NORMAL) { - for (int i=0; isymbols_per_slot; symb++) { reset = 1; - x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1)) + (Nid<<1); + x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid<<1)); for (uint32_t n=0; nframe_parms; + uint32_t ***csi_rs = gNB->nr_gold_csi_rs; + uint32_t x1, x2; + uint8_t reset; + + for (uint8_t slot=0; slotslots_per_frame; slot++) { + for (uint8_t symb=0; symbsymbols_per_slot; symb++) { + + reset = 1; + x2 = ((1<<10) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid)); + + for (uint32_t n=0; n>1]; + uint16_t b = csi_params.freq_domain; + uint16_t n, csi_bw, csi_start, p, k, l, mprime, na, kpn, csi_length; + uint8_t size, ports, kprime, lprime, i, gs; + uint8_t j[16], k_n[6], koverline[16], loverline[16]; + int found = 0; + int wf, wt, lp, kp, symb; + uint8_t fi = 0; + double rho, alpha; + uint32_t beta = amp; + + AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n"); + + switch (csi_params.row) { + // implementation of table 7.4.1.5.3-1 of 38.211 + // lprime and kprime are the max value of l' and k' + case 1: + ports = 1; + kprime = 0; + lprime = 0; + size = 3; + while (found < 1) { + if ((b >> fi) & 0x01) { + k_n[found] = fi; + found++; + } + else + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi; + found++; + } + else + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + else + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<2; + found++; + } + else + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + else + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i>1); + koverline[i] = k_n[i%2]; + } + break; + + case 8: + ports = 8; + kprime = 1; + lprime = 1; + size = 2; + while (found < 2) { + if ((b >> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i>2); + koverline[i] = k_n[i%4]; + } + break; + + case 12: + ports = 16; + kprime = 1; + lprime = 1; + size = 4; + while (found < 4) { + if ((b >> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i>2); + else + loverline[i] = csi_params.symb_l1 + (i/12); + koverline[i] = k_n[i%4]; + } + break; + + case 17: + ports = 32; + kprime = 1; + lprime = 1; + size = 8; + while (found < 4) { + if ((b >> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i> fi) & 0x01) { + k_n[found] = fi<<1; + found++; + } + fi++; + } + for (i=0; i (csi_params.bwp_start+csi_params.bwp_size-csi_start)) + csi_bw = csi_params.bwp_start+csi_params.bwp_size-csi_start; + else + csi_bw = csi_params.nr_of_rbs; + + if (rho < 1) { + if (csi_params.freq_density == 0) + csi_length = (((csi_bw + csi_start)>>1)<>1)<>15; + break; + + case 1: + beta = amp; + break; + + case 2: + beta = (amp*ONE_OVER_SQRT2_Q15)>>14; + break; + + case 3: + beta = amp<<1; + break; + + default: + AssertFatal(0==1, "Invalid SS power offset density index for CSI\n"); + } + + for (lp=0; lp<=lprime; lp++){ + symb = csi_params.symb_l0; + nr_modulation(gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]); + if ((csi_params.row == 5) || (csi_params.row == 7) || (csi_params.row == 11) || (csi_params.row == 13) || (csi_params.row == 16)) + nr_modulation(gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]); + if ((csi_params.row == 14) || (csi_params.row == 13) || (csi_params.row == 16) || (csi_params.row == 17)) { + symb = csi_params.symb_l1; + nr_modulation(gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]); + if ((csi_params.row == 13) || (csi_params.row == 16)) + nr_modulation(gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]); + } + } + + } + + uint16_t start_sc = frame_parms.first_carrier_offset; + + // resource mapping according to 38.211 7.4.1.5.3 + for (n=csi_start; n<(csi_start+csi_bw); n++) { + if ( (csi_params.freq_density > 1) || (csi_params.freq_density == (n%2))) { // for freq density 0.5 checks if even or odd RB + for (int ji=0; ji> 15; + ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15; + } +#ifdef NR_CSIRS_DEBUG + printf("l,k (%d %d) seq. index %d \t port %d \t (%d,%d)\n",l,k-start_sc,mprime,p+3000,((int16_t*)txdataF[p])[(l*frame_parms.ofdm_symbol_size + k)<<1], + ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1]); +#endif + } + } + } + } + } + } + + return 0; +} diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 4461edb33b..7b275ea981 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -140,7 +140,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs; int16_t **tx_layers = (int16_t**)dlsch->txdataF; - int8_t Wf[2], Wt[2], l0, l_prime[2], delta; + int8_t Wf[2], Wt[2], l0, l_prime, l_overline, delta; uint8_t dmrs_Type = rel15->dmrsConfigType; int nb_re_dmrs; uint16_t n_dmrs; @@ -153,10 +153,10 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1; } uint16_t nb_re; - nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords; + nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->nrOfLayers; uint8_t Qm = rel15->qamModOrder[0]; uint32_t encoded_length = nb_re*Qm; - int16_t mod_dmrs[n_dmrs<<1] __attribute__ ((aligned(16))); + int16_t mod_dmrs[14][n_dmrs] __attribute__ ((aligned(16))); /// CRC, coding, interleaving and rate matching @@ -248,18 +248,19 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, /// Antenna port mapping //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007 - + /// DMRS QPSK modulation - - - l0 = get_l0(rel15->dlDmrsSymbPos); - nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated - + for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { + if (rel15->dlDmrsSymbPos & (1 << l)) + nr_modulation(pdsch_dmrs[l][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + } + #ifdef DEBUG_DLSCH + l0 = get_l0(rel15->dlDmrsSymbPos); printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_Type); for (int i=0; i>4; i++) { for (int j=0; j<8; j++) { - printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]); + printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]); } printf("\n"); } @@ -283,55 +284,71 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, get_Wt(Wt, ap, dmrs_Type); get_Wf(Wf, ap, dmrs_Type); delta = get_delta(ap, dmrs_Type); - l_prime[0] = 0; // single symbol ap 0 - uint8_t dmrs_symbol = l0+l_prime[0]; + l_prime = 0; // single symbol ap 0 + l0 = get_l0(rel15->dlDmrsSymbPos); + l_overline = l0; + #ifdef DEBUG_DLSCH_MAPPING + uint8_t dmrs_symbol = l0+l_prime; printf("DMRS Type %d params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n", - 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); + 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime, l0, dmrs_symbol); #endif uint8_t k_prime=0; uint16_t m=0, n=0, dmrs_idx=0, k=0; int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; - if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k) - dmrs_idx = rel15->rbStart*6; - else - dmrs_idx = rel15->rbStart*4; - + for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { - k = start_sc; - for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) { - if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) { - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + k = start_sc; + n = 0; + k_prime = 0; + if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k) + dmrs_idx = rel15->rbStart*6; + else + dmrs_idx = rel15->rbStart*4; + for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) { + + if ((rel15->dlDmrsSymbPos & (1 << l)) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) { + + if (l==(l_overline+1)) //take into account the double DMRS symbols + l_prime = 1; + else if (l>(l_overline+1)) {//new DMRS pair + l_overline = l; + l_prime = 0; + } + + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][dmrs_idx<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING - printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", - dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); + printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", + dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif - dmrs_idx++; - k_prime++; - k_prime&=1; - n+=(k_prime)?0:1; - } - - else { - if( (l != dmrs_symbol) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) { - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; + dmrs_idx++; + k_prime++; + k_prime&=1; + n+=(k_prime)?0:1; + + } else { + + if( (!(rel15->dlDmrsSymbPos & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) { + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING - printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", - m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); + printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", + m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif - m++; - } - } - if (++k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; - } //RE loop + m++; + } + } + if (++k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; + } //RE loop } // symbol loop }// layer loop + + dlsch->slot_tx[slot]=0; }// dlsch loop return 0; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index a4a684c4e4..80d6d13d9e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -333,7 +333,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, uint8_t mod_order = rel15->qamModOrder[0]; uint16_t Kr=0,r; uint32_t r_offset=0; - uint8_t BG=1; uint32_t E; uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; //max tbs @@ -431,9 +430,9 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, Coderate = (float) R /(float) 2048; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) - BG = 2; + dlsch->harq_processes[harq_pid]->BG = 2; else - BG = 1; + dlsch->harq_processes[harq_pid]->BG = 1; start_meas(dlsch_segmentation_stats); Kb = nr_segmentation(dlsch->harq_processes[harq_pid]->b, @@ -443,7 +442,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, &dlsch->harq_processes[harq_pid]->K, Zc, &dlsch->harq_processes[harq_pid]->F, - BG); + dlsch->harq_processes[harq_pid]->BG); stop_meas(dlsch_segmentation_stats); F = dlsch->harq_processes[harq_pid]->F; @@ -480,7 +479,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) { impp.macro_num=j; - nrLDPC_encoder(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,&impp); + nrLDPC_encoder(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,dlsch->harq_processes[harq_pid]->BG,&impp); } @@ -532,7 +531,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, start_meas(dlsch_rate_matching_stats); nr_rate_matching_ldpc(Ilbrm, Tbslbrm, - BG, + dlsch->harq_processes[harq_pid]->BG, *Zc, dlsch->harq_processes[harq_pid]->d[r], dlsch->harq_processes[harq_pid]->e+r_offset, diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c index 04045380eb..e6a9b8c5dc 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c @@ -67,12 +67,12 @@ void get_antenna_ports(uint8_t *ap, uint8_t n_symbs, uint8_t config) { void get_Wt(int8_t *Wt, uint8_t ap, uint8_t config) { for (int i=0; i<2; i++) - *(Wt+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][3+i]):(pdsch_dmrs_2[ap][3+i]); + *(Wt+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][5+i]):(pdsch_dmrs_2[ap][5+i]); } void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config) { for (int i=0; i<2; i++) - *(Wf+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][5+i]):(pdsch_dmrs_2[ap][5+i]); + *(Wf+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][3+i]):(pdsch_dmrs_2[ap][3+i]); } uint8_t get_delta(uint8_t ap, uint8_t config) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h index a30c529459..be3ba00989 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h @@ -44,7 +44,7 @@ void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping, uint32_t n_id, uint8_t n_hop, - int nr_tti_tx, + int nr_slot_tx, uint8_t *u, uint8_t *v); @@ -53,7 +53,7 @@ double nr_cyclic_shift_hopping(uint32_t n_id, uint8_t mcs, uint8_t lnormal, uint8_t lprime, - int nr_tti_tx); + int nr_slot_tx); /** \brief Computes available bits G. */ uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t length_dmrs, uint8_t Qm, uint8_t Nl); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 417f0d41a3..5228cad98c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -327,6 +327,13 @@ int nr_find_pucch(uint16_t rnti, void init_prach_list(PHY_VARS_gNB *gNB); void init_prach_ru_list(RU_t *ru); void free_nr_ru_prach_entry(RU_t *ru, int prach_id); + +int nr_generate_csi_rs(uint32_t **gold_csi_rs, + int32_t **txdataF, + int16_t amp, + NR_DL_FRAME_PARMS frame_parms, + nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params); + void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id); void nr_decode_pucch1(int32_t **rxdataF, @@ -354,5 +361,10 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu); +void nr_decode_pucch2(PHY_VARS_gNB *gNB, + int slot, + nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, + nfapi_nr_pucch_pdu_t* pucch_pdu); + #endif /*__NR_TRANSPORT__H__*/ diff --git a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c index 2b0cbe72b3..4d286bc937 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c +++ b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c @@ -33,11 +33,11 @@ #include "nr_dci.h" void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, - uint32_t n_id, - uint8_t n_hop, - int nr_tti_tx, - uint8_t *u, - uint8_t *v) { + uint32_t n_id, + uint8_t n_hop, + int nr_slot_tx, + uint8_t *u, + uint8_t *v) { /* * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping * The following variables are set by higher layers: @@ -65,7 +65,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, *v=0; uint32_t c_init = 0; uint32_t x1,s; // TS 38.211 Subclause 5.2.1 - int l = 32, minShift = ((2*nr_tti_tx+n_hop)<<3); + int l = 32, minShift = ((2*nr_slot_tx+n_hop)<<3); int tmpShift =0; #ifdef DEBUG_NR_PUCCH_TX printf("\t\t [nr_group_sequence_hopping] calculating u,v -> "); @@ -92,7 +92,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, f_gh = f_gh%30; f_ss = n_id%30; /* for (int m=0; m<8; m++){ - f_gh = f_gh + ((1<>(8*(2*nr_tti_tx+n_hop)+m))&1))); // Not sure we have to use nr_tti_tx FIXME!!! + f_gh = f_gh + ((1<>(8*(2*nr_slot_tx+n_hop)+m))&1))); // Not sure we have to use nr_slot_tx FIXME!!! } f_gh = f_gh%30; f_ss = n_id%30;*/ @@ -102,7 +102,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 f_ss = n_id%30; - l = 32, minShift = (2*nr_tti_tx+n_hop); + l = 32, minShift = (2*nr_slot_tx+n_hop); while(minShift >= l) { s = lte_gold_generic(&x1, &c_init, 0); @@ -111,7 +111,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, tmpShift = (minShift&((1<<5)-1)); //minShift%32; *v = (uint8_t)((s>>tmpShift)&1); - // *v = (uint8_t)((s>>(2*nr_tti_tx+n_hop))&1); // Not sure we have to use nr_tti_tx FIXME!!! + // *v = (uint8_t)((s>>(2*nr_slot_tx+n_hop))&1); // Not sure we have to use nr_slot_tx FIXME!!! } *u = (f_gh+f_ss)%30; @@ -125,7 +125,7 @@ double nr_cyclic_shift_hopping(uint32_t n_id, uint8_t mcs, uint8_t lnormal, uint8_t lprime, - int nr_tti_tx) { + int nr_slot_tx) { /* * Implements TS 38.211 subclause 6.3.2.2.2 Cyclic shift hopping * - n_id: higher-layer parameter hoppingId @@ -140,7 +140,7 @@ double nr_cyclic_shift_hopping(uint32_t n_id, uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 uint8_t n_cs=0; - int l = 32, minShift = (14*8*nr_tti_tx )+ 8*(lnormal+lprime); + int l = 32, minShift = (14*8*nr_slot_tx )+ 8*(lnormal+lprime); int tmpShift =0; #ifdef DEBUG_NR_PUCCH_TX printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%u -> \n",c_init); @@ -155,8 +155,8 @@ double nr_cyclic_shift_hopping(uint32_t n_id, tmpShift = (minShift&((1<<5)-1)); //minShift%32; minShift ++; n_cs = n_cs+((1<>tmpShift)&1))); - // calculating n_cs (Not sure we have to use nr_tti_tx FIXME!!!) - // n_cs = n_cs+((1<>((14*8*nr_tti_tx) + 8*(lnormal+lprime) + m))&1))); + // calculating n_cs (Not sure we have to use nr_slot_tx FIXME!!!) + // n_cs = n_cs+((1<>((14*8*nr_slot_tx) + 8*(lnormal+lprime) + m))&1))); } alpha = (alpha * (double)((m0+mcs+n_cs)%12)); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 42f88d16f4..a528eb734c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -478,7 +478,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; - + + if (!harq_process) { + LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n"); + return 1; + } + t_nrLDPC_dec_params decParams; t_nrLDPC_dec_params* p_decParams = &decParams; @@ -488,11 +493,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, phy_vars_gNB->nbDecode = 0; harq_process->processedSegments = 0; - if (!harq_process) { - LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n"); - return 1; - } - double Coderate = 0.0; // ------------------------------------------------------------------ diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index b27e7496f7..4622c31db3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1136,8 +1136,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, rel15_ul); for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { - gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = signal_energy(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol*frame_parms->ofdm_symbol_size], - rel15_ul->rb_size*12); + gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = signal_energy_nodc(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol*frame_parms->ofdm_symbol_size], + rel15_ul->rb_size*12); if (gNB->pusch_vars[ulsch_id]->ulsch_power[aarx]==1) return (1); } diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index bee868b5a5..83a66b55fb 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -96,7 +96,6 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, pucch->slot = slot; pucch->active = 1; memcpy((void*)&pucch->pucch_pdu, (void*)pucch_pdu, sizeof(nfapi_nr_pucch_pdu_t)); - } @@ -166,7 +165,6 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu) { - int32_t **rxdataF = gNB->common_vars.rxdataF; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; @@ -381,7 +379,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, #endif // estimate CQI for MAC (from antenna port 0 only) - int SNRtimes10 = dB_fixed_times10(signal_energy(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12)) - (10*gNB->measurements.n0_power_tot_dB); + int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12)) - (10*gNB->measurements.n0_power_tot_dB); int cqi; if (SNRtimes10 < -640) cqi=0; else if (SNRtimes10 > 635) cqi=255; @@ -395,9 +393,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, // first bit of bitmap for sr presence and second bit for acknack presence uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1); uci_pdu->pucch_format = 0; // format 0 - uci_pdu->ul_cqi = cqi; // currently not valid + uci_pdu->ul_cqi = cqi; uci_pdu->timing_advance = 0xffff; // currently not valid - uci_pdu->rssi = 1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(signal_energy(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12))); + uci_pdu->rssi = 1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(signal_energy_nodc(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12))); if (pucch_pdu->bit_len_harq==0) { uci_pdu->harq = NULL; uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr)); @@ -414,8 +412,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0; uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1); uci_pdu->harq->harq_list[0].harq_value = index&0x01; - LOG_D(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n", - uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level); + LOG_D(PHY, "Slot %d HARQ value %d with confidence level (0 is good, 1 is bad) %d\n", + slot,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level); if (pucch_pdu->sr_flag == 1) { uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr)); uci_pdu->sr->sr_indication = (index>1) ? 1 : 0; @@ -429,8 +427,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2); uci_pdu->harq->harq_list[1].harq_value = index&0x01; uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01; - LOG_D(PHY, "HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n", - uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level); + LOG_D(PHY, "Slot %d HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n", + slot,uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level); if (pucch_pdu->sr_flag == 1) { uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr)); uci_pdu->sr->sr_indication = (index>3) ? 1 : 0; @@ -1091,11 +1089,12 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; //pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1); - - AssertFatal(pucch_pdu->nr_of_symbols==1 || pucch_pdu->nr_of_symbols==2, "Illegal number of symbols for PUCCH 2 %d\n",pucch_pdu->nr_of_symbols); + AssertFatal((pucch_pdu->prb_start-((pucch_pdu->prb_start>>2)<<2))==0, + "Current pucch2 receiver implementation requires a PRB offset multiple of 4. The one selected is %d", + pucch_pdu->prb_start); //extract pucch and dmrs first @@ -1118,10 +1117,24 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, int16_t rd_im_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32))); int16_t *r_re_ext_p,*r_im_ext_p,*rd_re_ext_p,*rd_im_ext_p; - int16_t *rp[Prx2]; + int nb_re_pucch = 12*pucch_pdu->prb_size; + + int16_t rp[Prx2][nb_re_pucch*2],*tmp_rp; __m64 dmrs_re,dmrs_im; - for (int aa=0;aaofdm_symbol_size)+re_offset]); + for (int aa=0;aaofdm_symbol_size]); + + if (re_offset + nb_re_pucch < frame_parms->ofdm_symbol_size) { + memcpy1((void*)rp[aa],(void*)&tmp_rp[re_offset*2],nb_re_pucch*sizeof(int32_t)); + } + else { + int neg_length = frame_parms->ofdm_symbol_size-re_offset; + int pos_length = nb_re_pucch-neg_length; + memcpy1((void*)rp[aa],(void*)&tmp_rp[re_offset*2],neg_length*sizeof(int32_t)); + memcpy1((void*)&rp[aa][neg_length*2],(void*)tmp_rp,pos_length*sizeof(int32_t)); + } + } #ifdef DEBUG_NR_PUCCH_RX printf("Decoding pucch2 for %d symbols, %d PRB\n",pucch_pdu->nr_of_symbols,pucch_pdu->prb_size); @@ -1142,67 +1155,19 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, rd_re_ext_p=&rd_re_ext[aa][4*prb]; rd_im_ext_p=&rd_im_ext[aa][4*prb]; - r_re_ext_p[0]=rp[aa][0]; - r_im_ext_p[0]=rp[aa][1]; - rd_re_ext_p[0]=rp[aa][2]; - rd_im_ext_p[0]=rp[aa][3]; - r_re_ext_p[1]=rp[aa][4]; - r_im_ext_p[1]=rp[aa][5]; - - r_re_ext_p[2]=rp[aa][6]; - r_im_ext_p[2]=rp[aa][7]; - rd_re_ext_p[1]=rp[aa][8]; - rd_im_ext_p[1]=rp[aa][9]; - r_re_ext_p[3]=rp[aa][10]; - r_im_ext_p[3]=rp[aa][11]; - - r_re_ext_p[4]=rp[aa][12]; - r_im_ext_p[4]=rp[aa][13]; - rd_re_ext_p[2]=rp[aa][14]; - rd_im_ext_p[2]=rp[aa][15]; - r_re_ext_p[5]=rp[aa][16]; - r_im_ext_p[5]=rp[aa][17]; - - r_re_ext_p[6]=rp[aa][18]; - r_im_ext_p[6]=rp[aa][19]; - rd_re_ext_p[3]=rp[aa][20]; - rd_im_ext_p[3]=rp[aa][21]; - r_re_ext_p[7]=rp[aa][22]; - r_im_ext_p[7]=rp[aa][23]; - - r_re_ext_p[8]=rp[aa][24]; - r_im_ext_p[8]=rp[aa][25]; - rd_re_ext_p[4]=rp[aa][26]; - rd_im_ext_p[4]=rp[aa][27]; - r_re_ext_p[9]=rp[aa][28]; - r_im_ext_p[9]=rp[aa][29]; - - r_re_ext_p[10]=rp[aa][30]; - r_im_ext_p[10]=rp[aa][31]; - rd_re_ext_p[5]=rp[aa][32]; - rd_im_ext_p[5]=rp[aa][33]; - r_re_ext_p[11]=rp[aa][34]; - r_im_ext_p[11]=rp[aa][35]; - - r_re_ext_p[12]=rp[aa][36]; - r_im_ext_p[12]=rp[aa][37]; - rd_re_ext_p[6]=rp[aa][38]; - rd_im_ext_p[6]=rp[aa][39]; - r_re_ext_p[13]=rp[aa][40]; - r_im_ext_p[13]=rp[aa][41]; - - r_re_ext_p[14]=rp[aa][42]; - r_im_ext_p[14]=rp[aa][43]; - rd_re_ext_p[7]=rp[aa][44]; - rd_im_ext_p[7]=rp[aa][45]; - r_re_ext_p[15]=rp[aa][46]; - r_im_ext_p[15]=rp[aa][47]; + for (int idx=0; idx<8; idx++) { + r_re_ext_p[idx<<1]=rp[aa][prb*24+6*idx]; + r_im_ext_p[idx<<1]=rp[aa][prb*24+1+6*idx]; + rd_re_ext_p[idx]=rp[aa][prb*24+2+6*idx]; + rd_im_ext_p[idx]=rp[aa][prb*24+3+6*idx]; + r_re_ext_p[1+(idx<<1)]=rp[aa][prb*24+4+6*idx]; + r_im_ext_p[1+(idx<<1)]=rp[aa][prb*24+5+6*idx]; + } #ifdef DEBUG_NR_PUCCH_RX for (int i=0;i<8;i++) printf("Ant %d PRB %d dmrs[%d] -> (%d,%d)\n",aa,prb+(i>>2),i,rd_re_ext_p[i],rd_im_ext_p[i]); for (int i=0;i<16;i++) printf("Ant %d PRB %d data[%d] -> (%d,%d)\n",aa,prb+(i>>3),i,r_re_ext_p[i],r_im_ext_p[i]); #endif - rp[aa]+=48; } // aa } // prb @@ -1214,7 +1179,11 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, printf("slot %d, start_symbol_index %d, dmrs_scrambling_id %d\n", slot,pucch_pdu->start_symbol_index,pucch_pdu->dmrs_scrambling_id); #endif - s = lte_gold_generic(&x1, &x2, 1); + int reset = 1; + for (int i=0; i<=(pucch_pdu->prb_start>>2); i++) { + s = lte_gold_generic(&x1, &x2, reset); + reset = 0; + } for (int group=0;group>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_re[aa]))[0]); corr_im = ( corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_im[aa]))[0]); corr_tmp += corr_re*corr_re + corr_im*corr_im; - /* - LOG_D(PHY,"pucch2 half_prb %d cw %d (%d,%d) aa %d: (%d,%d,%d,%d,%d,%d,%d,%d)x(%d,%d,%d,%d,%d,%d,%d,%d) (%d,%d)+(%d,%d) = (%d,%d) => %d\n", - half_prb,cw,cw&15,cw>>4,aa, - ((int16_t*)&pucch2_polar_4bit[cw&15])[0],((int16_t*)&pucch2_polar_4bit[cw>>4])[0], - ((int16_t*)&pucch2_polar_4bit[cw&15])[1],((int16_t*)&pucch2_polar_4bit[cw>>4])[1], - ((int16_t*)&pucch2_polar_4bit[cw&15])[2],((int16_t*)&pucch2_polar_4bit[cw>>4])[2], - ((int16_t*)&pucch2_polar_4bit[cw&15])[3],((int16_t*)&pucch2_polar_4bit[cw>>4])[3], - ((int16_t*)&rp_re[aa][half_prb])[0],((int16_t*)&rp_im[aa][half_prb])[0], - ((int16_t*)&rp_re[aa][half_prb])[1],((int16_t*)&rp_im[aa][half_prb])[1], - ((int16_t*)&rp_re[aa][half_prb])[2],((int16_t*)&rp_im[aa][half_prb])[2], - ((int16_t*)&rp_re[aa][half_prb])[3],((int16_t*)&rp_im[aa][half_prb])[3], - corr32_re[half_prb>>2][aa]/(2*nc_group_size*4/2),corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2), - ((int16_t*)(&prod_re[aa]))[0], - ((int16_t*)(&prod_im[aa]))[0], - corr_re, - corr_im, - corr_tmp); - */ + /* + LOG_D(PHY,"pucch2 half_prb %d cw %d (%d,%d) aa %d: (%d,%d,%d,%d,%d,%d,%d,%d)x(%d,%d,%d,%d,%d,%d,%d,%d) (%d,%d)+(%d,%d) = (%d,%d) => %d\n", + half_prb,cw,cw&15,cw>>4,aa, + ((int16_t*)&pucch2_polar_4bit[cw&15])[0],((int16_t*)&pucch2_polar_4bit[cw>>4])[0], + ((int16_t*)&pucch2_polar_4bit[cw&15])[1],((int16_t*)&pucch2_polar_4bit[cw>>4])[1], + ((int16_t*)&pucch2_polar_4bit[cw&15])[2],((int16_t*)&pucch2_polar_4bit[cw>>4])[2], + ((int16_t*)&pucch2_polar_4bit[cw&15])[3],((int16_t*)&pucch2_polar_4bit[cw>>4])[3], + ((int16_t*)&rp_re[aa][half_prb])[0],((int16_t*)&rp_im[aa][half_prb])[0], + ((int16_t*)&rp_re[aa][half_prb])[1],((int16_t*)&rp_im[aa][half_prb])[1], + ((int16_t*)&rp_re[aa][half_prb])[2],((int16_t*)&rp_im[aa][half_prb])[2], + ((int16_t*)&rp_re[aa][half_prb])[3],((int16_t*)&rp_im[aa][half_prb])[3], + corr32_re[half_prb>>2][aa]/(2*nc_group_size*4/2),corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2), + ((int16_t*)(&prod_re[aa]))[0], + ((int16_t*)(&prod_im[aa]))[0], + corr_re, + corr_im, + corr_tmp); + */ } corr16 = _mm_set1_epi16((int16_t)(corr_tmp>>8)); /* @@ -1625,26 +1594,34 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, } // half_prb // run polar decoder on llrs decoderState = polar_decoder_int16((int16_t*)llrs, decodedPayload, 0, currentPtr); - LOG_D(PHY,"UCI decoderState %d, payload[0] %llux\n",decoderState,(unsigned long long)decodedPayload[0]); + LOG_D(PHY,"UCI decoderState %d, payload[0] %llu\n",decoderState,(unsigned long long)decodedPayload[0]); if (decoderState>0) decoderState=1; corr_dB = dB_fixed64(corr); LOG_D(PHY,"metric %d dB\n",corr_dB); } + + re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset; + // estimate CQI for MAC (from antenna port 0 only) + int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset],12*pucch_pdu->prb_size)) - (10*gNB->measurements.n0_power_tot_dB); + int cqi; + if (SNRtimes10 < -640) cqi=0; + else if (SNRtimes10 > 635) cqi=255; + else cqi=(640+SNRtimes10)/5; + uci_pdu->harq.harq_bit_len = pucch_pdu->bit_len_harq; uci_pdu->pduBitmap=0; uci_pdu->rnti=pucch_pdu->rnti; uci_pdu->handle=pucch_pdu->handle; uci_pdu->pucch_format=0; - uci_pdu->ul_cqi=corr_dB; - // need to fill these field! - uci_pdu->timing_advance=31; - uci_pdu->rssi=0; + uci_pdu->ul_cqi=cqi; + uci_pdu->timing_advance=0xffff; // currently not valid + uci_pdu->rssi=1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(signal_energy_nodc(&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset],12*pucch_pdu->prb_size))); if (pucch_pdu->bit_len_harq>0) { int harq_bytes=pucch_pdu->bit_len_harq>>3; if ((pucch_pdu->bit_len_harq&7) > 0) harq_bytes++; uci_pdu->pduBitmap|=1; uci_pdu->harq.harq_payload = (uint8_t*)malloc(harq_bytes); - uci_pdu->harq.harq_crc = decoderState > 0 ? 1 : 0; + uci_pdu->harq.harq_crc = decoderState; int i=0; for (;iharq.harq_payload[i] = decodedPayload[0] & 255; @@ -1667,19 +1644,18 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, int csi_part1_bytes=pucch_pdu->bit_len_csi_part1>>3; if ((pucch_pdu->bit_len_csi_part1&7) > 0) csi_part1_bytes++; uci_pdu->csi_part1.csi_part1_payload = (uint8_t*)malloc(csi_part1_bytes); - uci_pdu->csi_part1.csi_part1_crc = decoderState > 0 ? 1 : 0; + uci_pdu->csi_part1.csi_part1_crc = decoderState; int i=0; for (;icsi_part1.csi_part1_payload[i] = decodedPayload[0] & 255; decodedPayload[0]>>=8; } uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_csi_part1&7))-1); - decodedPayload[0] >>= pucch_pdu->bit_len_csi_part1; + decodedPayload[0] >>= pucch_pdu->bit_len_csi_part1; } if (pucch_pdu->bit_len_csi_part2>0) { uci_pdu->pduBitmap|=8; } - } diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c index dec3d7cc2d..990f3101fd 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c @@ -185,3 +185,57 @@ short filt8_rr1[8] = { short filt8_rr2[8] = { -4096,-8192,-12288,-16384,0,0,0,0}; + +short filt8_l2[8] = { +0,0,13107,9830,6554,3277,0,0}; + +short filt8_r2[8] = { +0,0,3277,6554,9830,13107,0,0}; + +short filt8_m2[8] = { +0,0,0,0,13107,9830,6554,3277}; + +short filt8_mm2[8]= { +0,0,0,0,3277,6554,9830,13107}; + +short filt8_rl2[8] = { +19661,22938,26214,29491,0,0,0,0}; + +short filt8_rm2[8] = { +-3277,-6554,-9830,-13107,0,0,0,0};//-3277,-6554,-9830,-13107 + +short filt8_l3[8] = { +22938,19661,0,0,13107,9830,6554,3277}; + +short filt8_r3[8] = { +-7537,-4260,0,0,3277,6554,9830,13107};//-6554,-3277 + +short filt8_rl3[8] = { +0,0,19661,22938,0,0,0,0}; + +short filt8_rr3[8] = { +0,0,-4260,-7537,0,0,0,0};//-3277,-6554 + +short filt8_dcrl1[8] = { +14895,13405,11916,10426,8937,7447,5958,4468}; + +short filt8_dcrh1[8] = { +2979,1489,0,0,0,0,0,0}; + +short filt8_dcll1[8] = { +13405,14895,0,0,0,0,0,0}; + +short filt8_dclh1[8] = { +1489,2979,4468,5958,7447,8937,10426,11916}; + +short filt8_dcrl2[8] = { +0,0,0,0,14895,13405,11916,10426}; + +short filt8_dcrh2[8] = { +8937,7447,5958,4468,2979,1489,0,0,}; + +short filt8_dcll2[8] = { +7447,8937,10426,11916,13405,14895,0,0}; + +short filt8_dclh2[8] = { +0,0,0,0,1489,2979,4468,5958}; diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h index e350985b0a..ef6137a07f 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h @@ -133,4 +133,40 @@ extern short filt8_rr1[8]; extern short filt8_rr2[8]; +extern short filt8_rm2[8]; + +extern short filt8_rl2[8]; + +extern short filt8_l2[8]; + +extern short filt8_r2[8]; + +extern short filt8_m2[8]; + +extern short filt8_mm2[8]; + +extern short filt8_l3[8]; + +extern short filt8_r3[8]; + +extern short filt8_rr3[8]; + +extern short filt8_rl3[8]; + +extern short filt8_dcrl1[8]; + +extern short filt8_dcrh1[8]; + +extern short filt8_dcll1[8]; + +extern short filt8_dclh1[8]; + +extern short filt8_dcrl2[8]; + +extern short filt8_dcrh2[8]; + +extern short filt8_dcll2[8]; + +extern short filt8_dclh2[8]; + #endif \ No newline at end of file diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index b49443c03c..143871e2be 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -103,7 +103,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, if (ue->mac_enabled==1) { LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id); //mac_resynch(); - //dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id); + //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id); ue->UE_mode[0] = PRACH; ue->prach_resources[gNB_id]->sync_frame = frame; ue->prach_resources[gNB_id]->init_msg1 = 0; @@ -122,9 +122,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, #ifdef DEBUG_PHY - LOG_D(PHY,"AbsSubframe %d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n", + LOG_D(PHY,"AbsSubframe %d: diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n", subframe, - ue->current_thread_id[subframe], diff, ue->rx_offset, clear, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 71a5771f5b..bbf4036ab8 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -24,6 +24,7 @@ #include "SCHED_NR_UE/defs.h" #include "nr_estimation.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" #include "filt16a_32.h" //#define DEBUG_PDSCH @@ -31,6 +32,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned char symbol, @@ -48,7 +50,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, uint8_t nushift; uint8_t ssb_index=current_ssb->i_ssb; uint8_t n_hf=current_ssb->n_hf; - int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; nushift = ue->frame_parms.Nid_cell%4; ue->frame_parms.nushift = nushift; @@ -65,7 +67,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, k = nushift; #ifdef DEBUG_CH - printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ue->frame_parms.ofdm_symbol_size, + printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -192,6 +194,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned char symbol, @@ -211,7 +214,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t nushift; int **dl_ch_estimates =ue->pbch_vars[eNB_offset]->dl_ch_estimates; - int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; nushift = ue->frame_parms.Nid_cell%4; ue->frame_parms.nushift = nushift; @@ -233,7 +236,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, k = nushift; #ifdef DEBUG_CH - printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, + printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -445,19 +448,19 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, assert(0); } - if( symbol == 3) + if( dmrss == 2) // update time statistics for last PBCH symbol { - // do ifft of channel estimate - for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) - for (p=0; pframe_parms.nb_antenna_ports_gNB; p++) { - if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx]) - { - LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, ue->current_thread_id[Ns], symbol, ch_offset); - idft(idftsizeidx, - (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset], - (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1); - } - } + // do ifft of channel estimate + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) + for (p=0; pframe_parms.nb_antenna_ports_gNB; p++) { + if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx]) + { + LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, proc->thread_id, symbol, ch_offset); + idft(idftsizeidx, + (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset], + (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1); + } + } } //} @@ -467,6 +470,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, } int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned char symbol, @@ -482,8 +486,8 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; - int **dl_ch_estimates =ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates; - int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF; + int **dl_ch_estimates =ue->pdcch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage @@ -496,7 +500,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, k = coreset_start_subcarrier; #ifdef DEBUG_PDCCH - printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, + printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -641,6 +645,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, } int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned short p, @@ -652,18 +657,15 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned char aarx; unsigned short k; unsigned int pilot_cnt; - int16_t ch[2],*pil,*rxF,*dl_ch; - int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; + int16_t ch_l[2],ch_r[2],ch[2],*pil,*rxF,*dl_ch; + int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh, *frl, *frr; int ch_offset,symbol_offset; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; uint8_t nushift; - int **dl_ch_estimates =ue->pdsch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates; - int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF; - - nushift = (p>>1)&1; - ue->frame_parms.nushift = nushift; + int **dl_ch_estimates =ue->pdsch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage ch_offset = ue->frame_parms.ofdm_symbol_size ; @@ -676,55 +678,103 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int re_offset = k; #ifdef DEBUG_CH - printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, + printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif - switch (nushift) { - case 0: - fl = filt8_l0; - fm = filt8_m0; - fr = filt8_r0; - fmm = filt8_mm0; - fml = filt8_m0; - fmr = filt8_mr0; - fdcl = filt8_dcl0; - fdcr = filt8_dcr0; - fdclh = filt8_dcl0_h; - fdcrh = filt8_dcr0_h; - break; - - case 1: - fl = filt8_l1; - fm = filt8_m1; - fr = filt8_r1; - fmm = filt8_mm1; - fml = filt8_ml1; - fmr = filt8_m1; - fdcl = filt8_dcl1; - fdcr = filt8_dcr1; - fdclh = filt8_dcl1_h; - fdcrh = filt8_dcr1_h; - break; - - default: - msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); - return(-1); - break; - } - - - // generate pilot + // generate pilot for gNB port number 1000+p uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12; - int config_type = 0; // needs to be updated from higher layer - nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset); + uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; + int8_t delta = get_delta(p, config_type); + nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000+p,0,nb_rb_pdsch+rb_offset); + + if (config_type == pdsch_dmrs_type1){ + nushift = (p>>1)&1; + ue->frame_parms.nushift = nushift; + switch (delta) { + + case 0://port 0,1 + fl = filt8_l0;//left interpolation Filter for DMRS config. 1 + fm = filt8_m0;//left middle interpolation Filter + fr = filt8_r0;//right interpolation Filter + fmm = filt8_mm0;;//middle middle interpolation Filter + fml = filt8_m0;//left middle interpolation Filter + fmr = filt8_mr0;//middle right interpolation Filter + fdcl = filt8_dcl0;//left DC interpolation Filter (even RB) + fdcr = filt8_dcr0;//right DC interpolation Filter (even RB) + fdclh = filt8_dcl0_h;//left DC interpolation Filter (odd RB) + fdcrh = filt8_dcr0_h;//right DC interpolation Filter (odd RB) + frl = NULL; + frr = NULL; + break; + + case 1://port2,3 + fl = filt8_l1; + fm = filt8_m1; + fr = filt8_r1; + fmm = filt8_mm1; + fml = filt8_ml1; + fmr = filt8_m1; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; + frl = NULL; + frr = NULL; + break; + + default: + msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); + return -1; + break; + } + } else {//pdsch_dmrs_type2 + nushift = delta; + ue->frame_parms.nushift = nushift; + switch (delta) { + case 0://port 0,1 + fl = filt8_l2;//left interpolation Filter should be fml + fr = filt8_r2;//right interpolation Filter should be fmr + fm = filt8_l2; + fmm = filt8_r2; + fml = filt8_ml2; + fmr = filt8_mr2; + frl = filt8_rl2; + frr = filt8_rm2; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; + break; + + case 2://port2,3 + fl = filt8_l3; + fm = filt8_m2; + fr = filt8_r3; + fmm = filt8_mm2; + fml = filt8_l2; + fmr = filt8_r2; + frl = filt8_rl3; + frr = filt8_rr3; + fdcl = NULL; + fdcr = NULL; + fdclh = NULL; + fdcrh = NULL; + break; + + default: + msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); + return -1; + break; + } + } for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - - pil = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)]; + pil = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)]; k = k % ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; - dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + re_offset = k; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+re_offset+nushift)]; + dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha @@ -737,7 +787,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, printf("rxF addr %p p %d\n", rxF,p); printf("dl_ch addr %p nushift %d\n",dl_ch,nushift); #endif - //if ((ue->frame_parms.N_RB_DL&1)==0) { + + if (config_type == pdsch_dmrs_type1) { // Treat first 2 pilots specially (left edge) ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -867,7 +918,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch, dl_ch, 8); - //} // check if PRB crosses DC and improve estimates around DC if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) { @@ -875,7 +925,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); uint16_t idxPil = idxDC/2; re_offset = k; - pil = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)]; + pil = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)]; pil += (idxPil-2); dl_ch += (idxDC-4); dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10); @@ -920,20 +970,229 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); } + } + } else { //pdsch_dmrs_type2 |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0| + // Treat first 4 pilots specially (left edge) + ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PDSCH + printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); + printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch_l[0],ch_l[1],pil[0],pil[1]); +#endif + + pil+=2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_r[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + ch[0] = (ch_l[0]+ch_r[0])>>1; + ch[1] = (ch_l[1]+ch_r[1])>>1; + + dl_ch[(0+2*nushift)] = ch[0]; + dl_ch[(1+2*nushift)] = ch[1]; + dl_ch[2+2*nushift] = ch[0]; + dl_ch[3+2*nushift] = ch[1]; + + multadd_real_vector_complex_scalar(fl, + ch, + dl_ch, + 8); + + pil+=2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + pil+=2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_r[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + ch[0] = (ch_l[0]+ch_r[0])>>1; + ch[1] = (ch_l[1]+ch_r[1])>>1; + + multadd_real_vector_complex_scalar(fr, + ch, + dl_ch, + 8); + + dl_ch+=12; + dl_ch[0+2*nushift] = ch[0]; + dl_ch[1+2*nushift] = ch[1]; + dl_ch[2+2*nushift] = ch[0]; + dl_ch[3+2*nushift] = ch[1]; + dl_ch+=4; + + for (pilot_cnt=4; pilot_cnt<4*nb_rb_pdsch; pilot_cnt+=4) { + + multadd_real_vector_complex_scalar(fml, + ch, + dl_ch, + 8); + pil+=2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PDSCH + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch_l[0],ch_l[1],pil[0],pil[1]); +#endif + + pil+=2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_r[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + ch[0] = (ch_l[0]+ch_r[0])>>1; + ch[1] = (ch_l[1]+ch_r[1])>>1; + +#ifdef DEBUG_PDSCH + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch_r[0],ch_r[1],pil[0],pil[1]); +#endif + + multadd_real_vector_complex_scalar(fmr, + ch, + dl_ch, + 8); + + dl_ch+=8; + dl_ch[0+2*nushift] = ch[0]; + dl_ch[1+2*nushift] = ch[1]; + dl_ch[2+2*nushift] = ch[0]; + dl_ch[3+2*nushift] = ch[1]; + + multadd_real_vector_complex_scalar(fm, + ch, + dl_ch, + 8); + + pil+=2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + pil+=2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_r[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PDSCH + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch_r[0],ch_r[1],pil[0],pil[1]); +#endif + + ch[0] = (ch_l[0]+ch_r[0])>>1; + ch[1] = (ch_l[1]+ch_r[1])>>1; + + multadd_real_vector_complex_scalar(fmm, + ch, + dl_ch, + 8); + + dl_ch+=12; + dl_ch[0+2*nushift] = ch[0]; + dl_ch[1+2*nushift] = ch[1]; + dl_ch[2+2*nushift] = ch[0]; + dl_ch[3+2*nushift] = ch[1]; + dl_ch+=4; + } + + // Treat last 2 pilots specially (right edge) + // dl_ch-2+nushift<<1 + multadd_real_vector_complex_scalar(frl, + dl_ch-2+2*nushift, + dl_ch, + 8); + + multadd_real_vector_complex_scalar(frr, + dl_ch-14+2*nushift,/*14*/ + dl_ch, + 8); + + // check if PRB crosses DC and improve estimates around DC + if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size) && (p<2)) { + + dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; + uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); + dl_ch += (idxDC-8); + dl_ch = memset(dl_ch, 0, sizeof(int16_t)*20); + + dl_ch -= 2; + + ch_r[0] = dl_ch[0]; + ch_r[1]= dl_ch[1] ; + dl_ch += 22; + ch_l[0] = dl_ch[0]; + ch_l[1]= dl_ch[1] ; + + // for proper allignment of SIMD vectors + if((ue->frame_parms.N_RB_DL&1)==0) { + dl_ch -= 20; + //Interpolate fdcrl1 with ch_r + multadd_real_vector_complex_scalar(filt8_dcrl1, + ch_r, + dl_ch, + 8); + //Interpolate fdclh1 with ch_l + multadd_real_vector_complex_scalar(filt8_dclh1, + ch_l, + dl_ch, + 8); + dl_ch += 16; + //Interpolate fdcrh1 with ch_r + multadd_real_vector_complex_scalar(filt8_dcrh1, + ch_r, + dl_ch, + 8); + //Interpolate fdcll1 with ch_l + multadd_real_vector_complex_scalar(filt8_dcll1, + ch_l, + dl_ch, + 8); + } else { + dl_ch -= 28; + //Interpolate fdcrl1 with ch_r + multadd_real_vector_complex_scalar(filt8_dcrl2, + ch_r, + dl_ch, + 8); + //Interpolate fdclh1 with ch_l + multadd_real_vector_complex_scalar(filt8_dclh2, + ch_l, + dl_ch, + 8); + dl_ch += 16; + //Interpolate fdcrh1 with ch_r + multadd_real_vector_complex_scalar(filt8_dcrh2, + ch_r, + dl_ch, + 8); + //Interpolate fdcll1 with ch_l + multadd_real_vector_complex_scalar(filt8_dcll2, + ch_l, + dl_ch, + 8); + } + } } #ifdef DEBUG_PDSCH - dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; for(uint16_t idxP=0; idxPframe_parms.pdsch_config_common.referenceSignalPower*10))/10)); } +uint32_t get_nr_rx_total_gain_dB (module_id_t Mod_id,uint8_t CC_id) +{ + + PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; + + if (ue) + return ue->rx_total_gain_dB; + + return 0xFFFFFFFF; +} + + +float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index) +{ + + AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is null\n"); + AssertFatal(PHY_vars_UE_g[Mod_id]!=NULL,"PHY_vars_UE_g[%d] is null\n",Mod_id); + AssertFatal(PHY_vars_UE_g[Mod_id][CC_id]!=NULL,"PHY_vars_UE_g[%d][%d] is null\n",Mod_id,CC_id); + + PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; + + if (ue) + return (10*log10(ue->measurements.rsrp[gNB_index])- + get_nr_rx_total_gain_dB(Mod_id,0) - + 10*log10(20*12)); + return -140.0; +} + + void nr_ue_measurements(PHY_VARS_NR_UE *ue, - unsigned int subframe_offset, - unsigned char N0_symbol, - unsigned char abstraction_flag, - unsigned char rank_adaptation, - uint8_t subframe) + UE_nr_rxtx_proc_t *proc, + unsigned int subframe_offset, + unsigned char N0_symbol, + unsigned char abstraction_flag, + unsigned char rank_adaptation, + uint8_t subframe) { int aarx,aatx,eNB_id=0; //,gain_offset=0; //int rx_power[NUMBER_OF_CONNECTED_eNB_MAX]; @@ -101,7 +132,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; /*int16_t *dl_ch; - dl_ch = (int16_t *)&ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates[eNB_id][ch_offset];*/ + dl_ch = (int16_t *)&ue->pdsch_vars[proc->thread_id][0]->dl_ch_estimates[eNB_id][ch_offset];*/ ch_offset = ue->frame_parms.ofdm_symbol_size*2; @@ -112,7 +143,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, for (aarx=0; aarxnb_antennas_rx; aarx++) { for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) { ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = - (signal_energy_nodc(&ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates[eNB_id][ch_offset], + (signal_energy_nodc(&ue->pdsch_vars[proc->thread_id][0]->dl_ch_estimates[eNB_id][ch_offset], (50*12))); //- ue->measurements.n0_power[aarx]; @@ -191,4 +222,75 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, _mm_empty(); _m_empty(); #endif -} \ No newline at end of file +} + +void nr_ue_rsrp_measurements(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + uint8_t slot, + uint8_t abstraction_flag) +{ + int aarx,rb, symbol_offset; + int16_t *rxF; + + uint16_t Nid_cell = ue->frame_parms.Nid_cell; + uint8_t eNB_offset=0,l,nushift; + uint16_t off,nb_rb; +// NR_UE_MAC_INST_t *mac = get_mac_inst(0); + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; + + nushift = ue->frame_parms.Nid_cell%4; + ue->frame_parms.nushift = nushift; + unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; + if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size; + + symbol_offset = ue->frame_parms.ofdm_symbol_size*(ue->symbol_offset+1); + + ue->measurements.rsrp[eNB_offset] = 0; + + //if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){ + nb_rb = 20; + //} else{ + // LOG_E(PHY,"report quantity not supported \n"); + //} + + if (abstraction_flag == 0) { + + for (l=0; l<1; l++) { + + LOG_D(PHY,"[UE %d] slot %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, nushift %d, eNB_offset %d, l %d)\n",ue->Mod_id,slot,Nid_cell,nushift, + eNB_offset,l); + + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+ssb_offset+nushift)]; + off = 0; + + if (l==0) { + for (rb=0; rbmeasurements.rsrp[eNB_offset] += (((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1])); + //printf("rb %d, off %d : %d\n",rb,off,((((int32_t)rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1]))); + + off = (off+4) % ue->frame_parms.ofdm_symbol_size; + } + } + } + } + + ue->measurements.rsrp[eNB_offset]/=nb_rb; + + } else { + + ue->measurements.rsrp[eNB_offset] = -93 ; + } + + + if (eNB_offset == 0) + + LOG_I(PHY,"[UE %d] slot %d RRC Measurements (idx %d, Cell id %d) => rsrp: %3.1f dBm/RE (%d)\n", + ue->Mod_id, + slot,eNB_offset, + (eNB_offset>0) ? ue->measurements.adj_cell_id[eNB_offset-1] : ue->frame_parms.Nid_cell, + 10*log10(ue->measurements.rsrp[eNB_offset])-ue->rx_total_gain_dB, + ue->measurements.rsrp[eNB_offset]); + +} diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 53456bb691..9bfc11d64a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -665,12 +665,13 @@ void pdcch_siso(NR_DL_FRAME_PARMS *frame_parms, #ifdef NR_PDCCH_DCI_RUN int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, - uint32_t frame, - uint32_t slot) { + UE_nr_rxtx_proc_t *proc) { + uint32_t frame = proc->frame_rx; + uint32_t slot = proc->nr_slot_rx; NR_UE_COMMON *common_vars = &ue->common_vars; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[slot]][0]; + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0]; fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; uint8_t log2_maxh, aarx; @@ -684,7 +685,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, for (int s=rel15->coreset.StartSymbolIndex; s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); s++) { LOG_D(PHY,"in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); - nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[slot]].rxdataF, + nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, pdcch_vars->dl_ch_estimates, pdcch_vars->rxdataF_ext, pdcch_vars->dl_ch_estimates_ext, @@ -776,8 +777,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, #endif -void pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms, - uint8_t nr_tti_rx, +#if 0 +void nr_pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms, + uint8_t nr_slot_rx, uint8_t *e, uint32_t length) { int i; @@ -785,7 +787,7 @@ void pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms, uint32_t x1, x2, s=0; reset = 1; // x1 is set in lte_gold_generic - x2 = (nr_tti_rx<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 + x2 = (nr_slot_rx<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 for (i=0; i>(i&0x1f))&1); } } +#endif #ifdef NR_PDCCH_DCI_RUN @@ -836,11 +839,10 @@ void nr_pdcch_unscrambling(int16_t *z, #ifdef NR_PDCCH_DCI_RUN uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, - int frame, - int slot, - fapi_nr_dci_indication_t *dci_ind) { + UE_nr_rxtx_proc_t *proc, + fapi_nr_dci_indication_t *dci_ind) { - NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[slot]][0]; + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0]; fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; for (int i=0;inb_search_space;i++) { @@ -881,8 +883,8 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, if (crc == n_rnti) { LOG_D(PHY,"Decoded crc %x matches rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format_options[k]); - dci_ind->SFN = frame; - dci_ind->slot = slot; + dci_ind->SFN = proc->frame_rx; + dci_ind->slot = proc->nr_slot_rx; dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti; dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind; dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format_options[k]; @@ -906,7 +908,7 @@ void nr_dci_decoding_procedure0(int s, uint16_t coreset_nbr_rb, NR_UE_PDCCH **pdcch_vars, int do_common, - uint8_t nr_tti_rx, + uint8_t nr_slot_rx, NR_DCI_ALLOC_t *dci_alloc, int16_t eNB_id, uint8_t current_thread_id, @@ -941,7 +943,7 @@ void nr_dci_decoding_procedure0(int s, LOG_DDD("format_found is %d \n", *format_found); //if (mode == NO_DCI) { // #ifdef NR_PDCCH_DCI_DEBUG - // LOG_DDD("skip DCI decoding: expect no DCIs at nr_tti_rx %d in current searchSpace\n", nr_tti_rx); + // LOG_DDD("skip DCI decoding: expect no DCIs at nr_slot_rx %d in current searchSpace\n", nr_slot_rx); // #endif // return; //} @@ -975,8 +977,8 @@ void nr_dci_decoding_procedure0(int s, // } // if (mode == NO_DCI) { -// LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_tti_rx %d\n", -// nr_tti_rx); +// LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_slot_rx %d\n", +// nr_slot_rx); // return; // } @@ -1047,7 +1049,7 @@ void nr_dci_decoding_procedure0(int s, // compute Yk Yk = (unsigned int) pdcch_vars[eNB_id]->crnti; - for (i = 0; i <= nr_tti_rx; i++) + for (i = 0; i <= nr_slot_rx; i++) Yk = (Yk * A[p%3]) % 65537; } @@ -1316,7 +1318,7 @@ void nr_dci_decoding_procedure0(int s, } // store first nCCE of group for PUCCH transmission of ACK/NAK - pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind; // if (crc == si_rnti) { // dci_alloc[*dci_cnt].format = format_si; @@ -1327,7 +1329,7 @@ void nr_dci_decoding_procedure0(int s, // } else if (crc == ra_rnti) { // dci_alloc[*dci_cnt].format = format_ra; // // store first nCCE of group for PUCCH transmission of ACK/NAK - // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind; // *dci_cnt = *dci_cnt + 1; // } else if (crc == pdcch_vars[eNB_id]->crnti) { @@ -1338,23 +1340,23 @@ void nr_dci_decoding_procedure0(int s, // dci_alloc[*dci_cnt].format = format0; // *format0_found = 1; // *dci_cnt = *dci_cnt + 1; - // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind; // } // } else if (format_c == format0) { // this is a format 1A DCI // dci_alloc[*dci_cnt].format = format1A; // *dci_cnt = *dci_cnt + 1; - // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind; // } else { // // store first nCCE of group for PUCCH transmission of ACK/NAK // if (*format_c_found == 0) { // dci_alloc[*dci_cnt].format = format_c; // *dci_cnt = *dci_cnt + 1; // *format_c_found = 1; - // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind; // } // } // } - //LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[nr_tti_rx: %d]: %d ], AggregationLevel %d \n",format_c, nr_tti_rx, pdcch_vars[eNB_id]->nCCE[nr_tti_rx],L2); + //LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[nr_slot_rx: %d]: %d ], AggregationLevel %d \n",format_c, nr_slot_rx, pdcch_vars[eNB_id]->nCCE[nr_slot_rx],L2); // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); switch (1 << L) { case 1: @@ -1421,7 +1423,7 @@ uint8_t nr_dci_decoding_procedure(int s, NR_DCI_ALLOC_t *dci_alloc, NR_SEARCHSPACE_TYPE_t searchSpacetype, int16_t eNB_id, - uint8_t nr_tti_rx, + uint8_t nr_slot_rx, uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], uint16_t n_RB_ULBWP, uint16_t n_RB_DLBWP, @@ -1429,16 +1431,16 @@ uint8_t nr_dci_decoding_procedure(int s, format_found_t *format_found, uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]) { // uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - LOG_DD("(nr_dci_decoding_procedure) nr_tti_rx=%d n_RB_ULBWP=%d n_RB_DLBWP=%d format_found=%d\n", - nr_tti_rx,n_RB_ULBWP,n_RB_DLBWP,*format_found); + LOG_DD("(nr_dci_decoding_procedure) nr_slot_rx=%d n_RB_ULBWP=%d n_RB_DLBWP=%d format_found=%d\n", + nr_slot_rx,n_RB_ULBWP,n_RB_DLBWP,*format_found); int do_common = (int)searchSpacetype; uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS]; crc_scrambled_t crc_scrambled_ = *crc_scrambled; format_found_t format_found_ = *format_found; uint8_t dci_cnt = 0, old_dci_cnt = 0; uint32_t CCEmap0 = 0, CCEmap1 = 0, CCEmap2 = 0; - NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]]; - NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]; + NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_slot_rx]]; + NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_slot_rx]][eNB_id]; uint16_t pdcch_DMRS_scrambling_id = pdcch_vars2->coreset[p].pdcchDMRSScramblingID; uint64_t coreset_freq_dom = pdcch_vars2->coreset[p].frequencyDomainResources; int coreset_time_dur = pdcch_vars2->coreset[p].duration; @@ -1452,7 +1454,7 @@ uint8_t nr_dci_decoding_procedure(int s, coreset_nbr_rb = 6 * coreset_nbr_rb; // coreset_time_dur,coreset_nbr_rb, NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - //uint8_t mi;// = get_mi(&ue->frame_parms, nr_tti_rx); + //uint8_t mi;// = get_mi(&ue->frame_parms, nr_slot_rx); //uint8_t tmode = ue->transmission_mode[eNB_id]; //uint8_t frame_type = frame_parms->frame_type; uint8_t format_0_0_1_0_size_bits = 0, format_0_0_1_0_size_bytes = 0; //FIXME @@ -1487,7 +1489,7 @@ uint8_t nr_dci_decoding_procedure(int s, * Possible overlap between RE for SS/PBCH blocks (described in section 10, 38.213) has not been implemented yet * This can be implemented by setting variable 'mode = NO_DCI' when overlap occurs */ - //dci_detect_mode_t mode = 3; //dci_detect_mode_select(&ue->frame_parms, nr_tti_rx); + //dci_detect_mode_t mode = 3; //dci_detect_mode_select(&ue->frame_parms, nr_slot_rx); LOG_DD("searSpaceType=%d\n",do_common); LOG_DD("%s_dci_format=%d\n",do_common?"uss":"css",css_dci_format); @@ -1517,7 +1519,7 @@ uint8_t nr_dci_decoding_procedure(int s, // blind decoding (Type0-PDCCH,Type0A-PDCCH,Type1-PDCCH,Type2-PDCCH) // for format0_0 => we are NOT implementing format0_0 for common search spaces. FIXME! // for format0_0 and format1_0, first we calculate dci pdu size - format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0); + format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0); format_0_0_1_0_size_bytes = (format_0_0_1_0_size_bits%8 == 0) ? (uint8_t)floor(format_0_0_1_0_size_bits/8) : (uint8_t)(floor(format_0_0_1_0_size_bits/8) + 1); LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", css_dci_format,format_0_0_1_0_size_bits,format_0_0_1_0_size_bytes); @@ -1528,7 +1530,7 @@ uint8_t nr_dci_decoding_procedure(int s, LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat0_0_and_1_0, uformat0_0_and_1_0, format_0_0_1_0_size_bits, format_0_0_1_0_size_bytes, &dci_cnt, @@ -1537,7 +1539,7 @@ uint8_t nr_dci_decoding_procedure(int s, if (dci_cnt != old_dci_cnt) { // we will exit the loop as we have found the DCI aggregationLevel = 5; - format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,crc_scrambled_,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes, + format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,crc_scrambled_,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes, 0); // after decoding dci successfully we recalculate dci pdu size with correct crc scrambled to get the right field sizes old_dci_cnt = dci_cnt; @@ -1552,7 +1554,7 @@ uint8_t nr_dci_decoding_procedure(int s, // or TPC-PUSCH-RNTI, or TPC-PUCCH-RNTI, or TPC-SRS-RNTI, or C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI if (css_dci_format == cformat2_0) { // for format2_0, first we calculate dci pdu size - format_2_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_sfi_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,4); + format_2_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_sfi_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,4); format_2_0_size_bytes = (format_2_0_size_bits%8 == 0) ? (uint8_t)floor(format_2_0_size_bits/8) : (uint8_t)(floor(format_2_0_size_bits/8) + 1); LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_0_size_bits=%d, format2_0_size_bytes=%d\n", css_dci_format,format_2_0_size_bits,format_2_0_size_bytes); @@ -1562,7 +1564,7 @@ uint8_t nr_dci_decoding_procedure(int s, css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevelSFI, cformat2_0, uformat0_0_and_1_0, format_2_0_size_bits, format_2_0_size_bytes, &dci_cnt, @@ -1582,7 +1584,7 @@ uint8_t nr_dci_decoding_procedure(int s, if (css_dci_format == cformat2_1) { // for format2_1, first we calculate dci pdu size - format_2_1_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_int_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,5); + format_2_1_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_int_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,5); format_2_1_size_bytes = (format_2_1_size_bits%8 == 0) ? (uint8_t)floor(format_2_1_size_bits/8) : (uint8_t)(floor(format_2_1_size_bits/8) + 1); LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_1_size_bits=%d, format2_1_size_bytes=%d\n", css_dci_format,format_2_1_size_bits,format_2_1_size_bytes); @@ -1592,7 +1594,7 @@ uint8_t nr_dci_decoding_procedure(int s, css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat2_1, uformat0_0_and_1_0, format_2_1_size_bits, format_2_1_size_bytes, &dci_cnt, @@ -1612,7 +1614,7 @@ uint8_t nr_dci_decoding_procedure(int s, if (css_dci_format == cformat2_2) { // for format2_2, first we calculate dci pdu size - format_2_2_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_tpc_pucch_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,6); + format_2_2_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_tpc_pucch_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,6); format_2_2_size_bytes = (format_2_2_size_bits%8 == 0) ? (uint8_t)floor(format_2_2_size_bits/8) : (uint8_t)(floor(format_2_2_size_bits/8) + 1); LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_2_size_bits=%d, format2_2_size_bytes=%d\n", css_dci_format,format_2_2_size_bits,format_2_2_size_bytes); @@ -1622,7 +1624,7 @@ uint8_t nr_dci_decoding_procedure(int s, css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat2_2, uformat0_0_and_1_0, format_2_2_size_bits, format_2_2_size_bytes, &dci_cnt, @@ -1642,7 +1644,7 @@ uint8_t nr_dci_decoding_procedure(int s, if (css_dci_format == cformat2_3) { // for format2_1, first we calculate dci pdu size - format_2_3_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_tpc_srs_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,7); + format_2_3_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_tpc_srs_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,7); format_2_3_size_bytes = (format_2_3_size_bits%8 == 0) ? (uint8_t)floor(format_2_3_size_bits/8) : (uint8_t)(floor(format_2_3_size_bits/8) + 1); LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_3_size_bits=%d, format2_3_size_bytes=%d\n", css_dci_format,format_2_3_size_bits,format_2_3_size_bytes); @@ -1652,7 +1654,7 @@ uint8_t nr_dci_decoding_procedure(int s, css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat2_3, uformat0_0_and_1_0, format_2_3_size_bits, format_2_3_size_bytes, &dci_cnt, @@ -1673,7 +1675,7 @@ uint8_t nr_dci_decoding_procedure(int s, // UE-specific search space for a DCI format with CRC scrambled by C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI if (uss_dci_format == uformat0_0_and_1_0) { // for format0_0 and format1_0, first we calculate dci pdu size - format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0); + format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0); format_0_0_1_0_size_bytes = (format_0_0_1_0_size_bits%8 == 0) ? (uint8_t)floor(format_0_0_1_0_size_bits/8) : (uint8_t)(floor(format_0_0_1_0_size_bits/8) + 1); LOG_DD("calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", css_dci_format,format_0_0_1_0_size_bits,format_0_0_1_0_size_bytes); @@ -1684,7 +1686,7 @@ uint8_t nr_dci_decoding_procedure(int s, LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 0, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat0_0_and_1_0, uformat0_0_and_1_0, format_0_0_1_0_size_bits, format_0_0_1_0_size_bytes, &dci_cnt, @@ -1704,7 +1706,7 @@ uint8_t nr_dci_decoding_procedure(int s, if (uss_dci_format == uformat0_1_and_1_1) { // for format0_0 and format1_0, first we calculate dci pdu size - format_0_1_1_1_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,1); + format_0_1_1_1_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,1); format_0_1_1_1_size_bytes = (format_0_1_1_1_size_bits%8 == 0) ? (uint8_t)floor(format_0_1_1_1_size_bits/8) : (uint8_t)(floor(format_0_1_1_1_size_bits/8) + 1); LOG_DD("calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_1_1_1_size_bits=%d, format_0_1_1_1_size_bytes=%d\n", css_dci_format,format_0_1_1_1_size_bits,format_0_1_1_1_size_bytes); @@ -1715,7 +1717,7 @@ uint8_t nr_dci_decoding_procedure(int s, LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 0, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat0_0_and_1_0, uformat0_1_and_1_1, format_0_1_1_1_size_bits, format_0_1_1_1_size_bytes, &dci_cnt, diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c index 347c9c2ab9..fa09093306 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c @@ -59,7 +59,7 @@ -uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t nr_tti_rx) { +uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t slot) { /* #ifdef DEBUG_DCI if (frame_parms->frame_type == TDD) @@ -69,11 +69,11 @@ uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8 #endif */ uint8_t ret = 255; - uint8_t subframe = nr_tti_rx>>((int)(log2 (frame_parms->ttis_per_subframe))); + uint8_t subframe = slot / frame_parms->slots_per_subframe; AssertFatal(1==0,"Not ready for this ...\n"); if (frame_parms->frame_type == FDD) { - ret = (((frame<<1)+nr_tti_rx)&7); + ret = (((frame<<1)+slot)&7); } else { } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 7378f69c27..61d6c72ddf 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -218,16 +218,18 @@ void nr_dlsch_unscrambling(int16_t* llr, } uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, - short *dlsch_llr, - NR_DL_FRAME_PARMS *frame_parms, - NR_UE_DLSCH_t *dlsch, - NR_DL_UE_HARQ_t *harq_process, - uint32_t frame, - uint16_t nb_symb_sch, - uint8_t nr_tti_rx, - uint8_t harq_pid, - uint8_t is_crnti, - uint8_t llr8_flag) + UE_nr_rxtx_proc_t *proc, + int eNB_id, + short *dlsch_llr, + NR_DL_FRAME_PARMS *frame_parms, + NR_UE_DLSCH_t *dlsch, + NR_DL_UE_HARQ_t *harq_process, + uint32_t frame, + uint16_t nb_symb_sch, + uint8_t nr_slot_rx, + uint8_t harq_pid, + uint8_t is_crnti, + uint8_t llr8_flag) { #if UE_TIMING_TRACE @@ -253,13 +255,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf; + // HARQ stats + phy_vars_ue->dl_stats[harq_process->round]++; int16_t z [68*384]; int8_t l [68*384]; //__m128i l; //int16_t inv_d [68*384]; uint8_t kc; - uint8_t Ilbrm = 0; + uint8_t Ilbrm = 1; uint32_t Tbslbrm;// = 950984; uint16_t nb_rb;// = 30; @@ -296,14 +300,14 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return(dlsch->max_ldpc_iterations + 1); } - /*if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) { - printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx); + /*if (nr_slot_rx> (frame_parms->slots_per_frame-1)) { + printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx); return(dlsch->max_ldpc_iterations + 1); }*/ /*if (harq_process->harq_ack.ack != 2) { LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n", - phy_vars_ue->Mod_id, nr_tti_rx, harq_process->harq_ack.ack); + phy_vars_ue->Mod_id, nr_slot_rx, harq_process->harq_ack.ack); }*/ // nb_rb = dlsch->nb_rb; @@ -314,7 +318,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return(max_ldpc_iterations + 1); }*/ - /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]]; + /*harq_pid = dlsch->current_harq_pid[proc->thread_id]; if (harq_pid >= 8) { printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid); return(max_ldpc_iterations + 1); @@ -551,7 +555,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, start_meas(dlsch_turbo_decoding_stats); #endif - //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A); + //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_slot_rx,r,harq_process->C-1, A); //printf("harq process dr iteration %d\n", p_decParams->numMaxIter); @@ -644,46 +648,39 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break; - LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); + LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1); err_flag = 1; } } - int32_t frame_rx_prev = frame; - int32_t tti_rx_prev = nr_tti_rx - 1; - if (tti_rx_prev < 0) { - frame_rx_prev--; - tti_rx_prev += 10*frame_parms->ttis_per_subframe; - } - frame_rx_prev = frame_rx_prev%1024; - if (err_flag == 1) { //#if UE_DEBUG_TRACE LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", - phy_vars_ue->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); + phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); //#endif harq_process->harq_ack.ack = 0; harq_process->harq_ack.harq_id = harq_pid; harq_process->harq_ack.send_harq_status = 1; harq_process->errors[harq_process->round]++; - // printf("Rate: [UE %d] DLSCH: Setting NACK for slot %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round); + // printf("Rate: [UE %d] DLSCH: Setting NACK for slot %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round); if (harq_process->round >= dlsch->Mlimit) { harq_process->status = SCH_IDLE; harq_process->round = 0; + phy_vars_ue->dl_stats[4]++; } if(is_crnti) { - LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", - phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); + LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); } return((1 + dlsch->max_ldpc_iterations)); } else { //#if UE_DEBUG_TRACE - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", - phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", + phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); //#endif harq_process->status = SCH_IDLE; @@ -697,7 +694,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if(is_crnti) { - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS); + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round,harq_process->TBS); } //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); @@ -766,7 +763,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, NR_DL_UE_HARQ_t *harq_process, uint32_t frame, uint16_t nb_symb_sch, - uint8_t nr_tti_rx, + uint8_t nr_slot_rx, uint8_t harq_pid, uint8_t is_crnti, uint8_t llr8_flag) @@ -843,14 +840,14 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, return(dlsch->max_ldpc_iterations); } - /* if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) { - printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx); + /* if (nr_slot_rx> (frame_parms->slots_per_frame-1)) { + printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx); return(dlsch->max_ldpc_iterations); } - if (dlsch->harq_ack[nr_tti_rx].ack != 2) { + if (dlsch->harq_ack[nr_slot_rx].ack != 2) { LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n", - phy_vars_ue->Mod_id, nr_tti_rx, dlsch->harq_ack[nr_tti_rx].ack); + phy_vars_ue->Mod_id, nr_slot_rx, dlsch->harq_ack[nr_slot_rx].ack); }*/ /* @@ -859,7 +856,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, return(max_ldpc_iterations); }*/ - /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]]; + /*harq_pid = dlsch->current_harq_pid[proc->thread_id]; if (harq_pid >= 8) { printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid); return(max_ldpc_iterations); @@ -987,15 +984,16 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, memset(&curMsg->proc, 0, sizeof(curMsg->proc)); - curMsg->proc.frame_rx = proc->frame_rx; - curMsg->proc.nr_tti_rx = proc->nr_tti_rx; - curMsg->proc.num_seg = nb_seg; + curMsg->proc.frame_rx = proc->frame_rx; + curMsg->proc.nr_slot_rx = proc->nr_slot_rx; + curMsg->proc.thread_id = proc->thread_id; + curMsg->proc.num_seg = nb_seg; curMsg->proc.eNB_id= eNB_id; curMsg->proc.harq_pid=harq_pid; curMsg->proc.llr8_flag = llr8_flag; - msgToPush_dl->key= (nr_tti_rx%2) ? (nb_seg+30): nb_seg; + msgToPush_dl->key= (nr_slot_rx%2) ? (nb_seg+30): nb_seg; pushTpool(Tpool_dl, msgToPush_dl); /*Qm= harq_process->Qm; @@ -1149,7 +1147,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #if UE_TIMING_TRACE start_meas(dlsch_turbo_decoding_stats); #endif - LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); + LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1); /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ inv_d[cnt] = (1)*harq_process->d[r][cnt]; @@ -1241,23 +1239,15 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break; - LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); + LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1); err_flag = 1; } //} //loop r - int32_t frame_rx_prev = frame; - int32_t tti_rx_prev = nr_tti_rx - 1; - if (tti_rx_prev < 0) { - frame_rx_prev--; - tti_rx_prev += 10*frame_parms->ttis_per_subframe; - } - frame_rx_prev = frame_rx_prev%1024; - if (err_flag == 1) { #if UE_DEBUG_TRACE LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", - phy_vars_ue->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); + phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); #endif harq_process->harq_ack.ack = 0; harq_process->harq_ack.harq_id = harq_pid; @@ -1273,15 +1263,15 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, } if(is_crnti) { - LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", - phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS); + LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS); } return((1+dlsch->max_ldpc_iterations)); } else { #if UE_DEBUG_TRACE - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d\n", - phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d\n", + phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); #endif harq_process->status = SCH_IDLE; @@ -1294,7 +1284,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, if(is_crnti) { - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS); + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round,harq_process->TBS); } //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); @@ -1393,7 +1383,7 @@ void nr_dlsch_decoding_process(void *arg) __m128i *pl = (__m128i*)&l; proc->instance_cnt_dlsch_td=-1; - //proc->nr_tti_rx=proc->sub_frame_start; + //proc->nr_slot_rx = proc->sub_frame_start * frame_parms->slots_per_subframe; proc->decoder_thread_available = 1; @@ -1417,16 +1407,16 @@ void nr_dlsch_decoding_process(void *arg) int harq_pid = proc->harq_pid; llr8_flag1 = proc->llr8_flag; int frame = proc->frame_rx; - int slot = proc->nr_tti_rx; + int slot = proc->nr_slot_rx; r = proc->num_seg; - NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[slot]][eNB_id][0]; + NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[proc->thread_id][eNB_id][0]; NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[harq_pid]; - short *dlsch_llr = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[slot]][eNB_id]->llr[0]; + short *dlsch_llr = phy_vars_ue->pdsch_vars[proc->thread_id][eNB_id]->llr[0]; //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag); p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r]; nb_symb_sch = harq_process->nb_symbols; - printf("dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_tti_rx, proc->num_seg, r, harq_process->nb_symbols); + printf("dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_slot_rx, proc->num_seg, r, harq_process->nb_symbols); /* @@ -1435,7 +1425,7 @@ void nr_dlsch_decoding_process(void *arg) return(max_ldpc_iterations); }*/ - /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]]; + /*harq_pid = dlsch->current_harq_pid[proc->thread_id]; if (harq_pid >= 8) { printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid); return(max_ldpc_iterations); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index e8204ad0b5..51e34e0c89 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -100,16 +100,17 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw, int16_t **llr_layers); int nr_rx_pdsch(PHY_VARS_NR_UE *ue, - PDSCH_t type, - unsigned char eNB_id, - unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference - uint32_t frame, - uint8_t nr_tti_rx, - unsigned char symbol, - unsigned char first_symbol_flag, - RX_type_t rx_type, - unsigned char i_mod, - unsigned char harq_pid) + UE_nr_rxtx_proc_t *proc, + PDSCH_t type, + unsigned char eNB_id, + unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference + uint32_t frame, + uint8_t nr_slot_rx, + unsigned char symbol, + unsigned char first_symbol_flag, + RX_type_t rx_type, + unsigned char i_mod, + unsigned char harq_pid) { NR_UE_COMMON *common_vars = &ue->common_vars; @@ -151,42 +152,43 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, uint32_t llr_offset_symbol; //uint16_t bundle_L = 2; uint8_t pilots=0; + uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; uint16_t n_tx=1, n_rx=1; int32_t median[16]; uint32_t len; switch (type) { case SI_PDSCH: - pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]]; + pdsch_vars = ue->pdsch_vars[proc->thread_id]; dlsch = &ue->dlsch_SI[eNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; break; case RA_PDSCH: - pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]]; + pdsch_vars = ue->pdsch_vars[proc->thread_id]; dlsch = &ue->dlsch_ra[eNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; break; case PDSCH: - pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]]; - dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id]; + pdsch_vars = ue->pdsch_vars[proc->thread_id]; + dlsch = ue->dlsch[proc->thread_id][eNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; dlsch1_harq = dlsch[1]->harq_processes[harq_pid]; beamforming_mode = ue->transmission_mode[eNB_id] < 7 ? 0 :ue->transmission_mode[eNB_id]; break; default: - LOG_E(PHY, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type); + LOG_E(PHY, "[UE][FATAL] nr_slot_rx %d: Unknown PDSCH format %d\n", nr_slot_rx, type); return -1; break; } if (dlsch0_harq && dlsch1_harq){ - LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_tti_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status); + LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_slot_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status); if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status == ACTIVE)){ codeword_TB0 = dlsch0_harq->codeword; @@ -220,7 +222,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, return -1; } else { - LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx); + LOG_E(PHY,"[UE][FATAL] nr_slot_rx %d: no active DLSCH\n", nr_slot_rx); return(-1); } } else if (dlsch0_harq) { @@ -232,7 +234,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, printf("[DEMOD] I am assuming only TB0 is active\n"); #endif } else { - LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx); + LOG_E(PHY,"[UE][FATAL] nr_slot_rx %d: no active DLSCH\n", nr_slot_rx); return (-1); } } else { @@ -242,6 +244,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch0_harq->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); dlsch0_harq->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); + if (dlsch0_harq->Qm == 0 || dlsch0_harq->R == 0) { + LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n"); + return -1; + } #ifdef DEBUG_HARQ printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode); @@ -308,9 +314,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #endif #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif - nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF, + nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, pdsch_vars[eNB_id]->dl_ch_estimates, pdsch_vars[eNB_id]->rxdataF_ext, pdsch_vars[eNB_id]->dl_ch_estimates_ext, @@ -320,7 +326,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pilots, start_rb, nb_rb_pdsch, - nr_tti_rx, + nr_slot_rx, ue->high_speed_flag, frame_parms, dlsch0_harq->mimo_mode); @@ -333,7 +339,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, if (rx_type >= rx_IC_single_stream) { if (eNB_id_in_connected_eNB) // we are in TM5 - nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF, + nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, pdsch_vars[eNB_id]->dl_ch_estimates, pdsch_vars[eNB_id_i]->rxdataF_ext, pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, @@ -343,12 +349,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pilots, start_rb, nb_rb_pdsch, - nr_tti_rx, + nr_slot_rx, ue->high_speed_flag, frame_parms, dlsch0_harq->mimo_mode); else - nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF, + nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, pdsch_vars[eNB_id]->dl_ch_estimates, pdsch_vars[eNB_id_i]->rxdataF_ext, pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, @@ -358,14 +364,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pilots, start_rb, nb_rb_pdsch, - nr_tti_rx, + nr_slot_rx, ue->high_speed_flag, frame_parms, dlsch0_harq->mimo_mode); } } else if (beamforming_mode==0) { //else if nb_antennas_ports_gNB==1 && beamforming_mode == 0 - //printf("start nr dlsch extract nr_tti_rx %d thread id %d \n", nr_tti_rx, ue->current_thread_id[nr_tti_rx]); - nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF, + //printf("start nr dlsch extract nr_slot_rx %d thread id %d \n", nr_slot_rx, proc->thread_id); + nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, pdsch_vars[eNB_id]->dl_ch_estimates, pdsch_vars[eNB_id]->rxdataF_ext, pdsch_vars[eNB_id]->dl_ch_estimates_ext, @@ -373,9 +379,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->pmi_ext, symbol, pilots, + config_type, start_rb, nb_rb_pdsch, - nr_tti_rx, + nr_slot_rx, ue->high_speed_flag, frame_parms); @@ -389,21 +396,21 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, return(-1); } - len = (pilots==1)? (nb_rb*6):(nb_rb*12); + len = (pilots==1)? ((config_type==pdsch_dmrs_type1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12); #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X printf("[AbsSFN %u.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n", - frame,nr_tti_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + frame,nr_slot_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n", - frame,nr_tti_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + frame,nr_slot_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif n_tx = frame_parms->nb_antenna_ports_gNB; n_rx = frame_parms->nb_antennas_rx; @@ -413,19 +420,20 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch, symbol, pilots, + len, nb_rb); #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif if (first_symbol_flag==1) { if (beamforming_mode==0){ @@ -466,7 +474,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } //#ifdef UE_DEBUG_TRACE LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", - frame%1024,nr_tti_rx, pdsch_vars[eNB_id]->log2_maxh, + frame%1024,nr_slot_rx, pdsch_vars[eNB_id]->log2_maxh, pdsch_vars[eNB_id]->log2_maxh0, pdsch_vars[eNB_id]->log2_maxh1, avg[0],avgs); @@ -489,23 +497,23 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if T_TRACER if (type == PDSCH) { - T(T_UE_PHY_PDSCH_ENERGY, T_INT(eNB_id), T_INT(0), T_INT(frame%1024), T_INT(nr_tti_rx), + T(T_UE_PHY_PDSCH_ENERGY, T_INT(eNB_id), T_INT(0), T_INT(frame%1024), T_INT(nr_slot_rx), T_INT(avg[0]), T_INT(avg[1]), T_INT(avg[2]), T_INT(avg[3])); } #endif #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_tti_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_tti_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif // Now channel compensation if (dlsch0_harq->mimo_modegeneric_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_slot_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_slot_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif // MRC #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif if (frame_parms->nb_antennas_rx > 1) { @@ -653,17 +661,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif //printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol); // compute LLRs @@ -684,14 +692,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol; - /*LOG_I(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n", + LOG_D(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d energy %d\n", symbol, nb_rb,dlsch0_harq->Qm, pdsch_vars[eNB_id]->llr_length[symbol], pdsch_vars[eNB_id]->llr_offset[symbol], - (int16_t*)pdsch_vars[eNB_id]->llr[0], - pllr_symbol_cw0);*/ - + signal_energy(pdsch_vars[eNB_id]->rxdataF_comp0[0], 7*2*frame_parms->N_RB_DL*12)); + + /*printf("compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n", symbol, nb_rb,dlsch0_harq->Qm, @@ -731,7 +739,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho2_ext, pdsch_vars[eNB_id]->layer_llr[0], symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128); if (rx_type==rx_IC_dual_stream) { nr_dlsch_qpsk_qpsk_llr(frame_parms, @@ -740,7 +748,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pdsch_vars[eNB_id]->layer_llr[1], symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128_2ndstream); } } @@ -752,7 +760,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho2_ext, pdsch_vars[eNB_id]->layer_llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128); if (rx_type==rx_IC_dual_stream) { nr_dlsch_16qam_qpsk_llr(frame_parms, @@ -762,7 +770,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pdsch_vars[eNB_id]->layer_llr[1], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128_2ndstream); } } @@ -774,7 +782,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho2_ext, pdsch_vars[eNB_id]->layer_llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128); if (rx_type==rx_IC_dual_stream) { nr_dlsch_64qam_qpsk_llr(frame_parms, @@ -784,7 +792,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pdsch_vars[eNB_id]->layer_llr[1], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128_2ndstream); } } @@ -817,7 +825,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho2_ext, pdsch_vars[eNB_id]->layer_llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128); if (rx_type==rx_IC_dual_stream) { nr_dlsch_qpsk_16qam_llr(frame_parms, @@ -827,7 +835,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pdsch_vars[eNB_id]->layer_llr[1], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128_2ndstream); } } @@ -840,7 +848,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho2_ext, pdsch_vars[eNB_id]->layer_llr[0], symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128); if (rx_type==rx_IC_dual_stream) { nr_dlsch_16qam_16qam_llr(frame_parms, @@ -851,7 +859,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pdsch_vars[eNB_id]->layer_llr[1], symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128_2ndstream); } } @@ -864,7 +872,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho2_ext, pdsch_vars[eNB_id]->layer_llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128); if (rx_type==rx_IC_dual_stream) { nr_dlsch_64qam_16qam_llr(frame_parms, @@ -875,7 +883,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pdsch_vars[eNB_id]->layer_llr[1], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128_2ndstream); } } @@ -910,7 +918,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho2_ext, pdsch_vars[eNB_id]->layer_llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128); if (rx_type==rx_IC_dual_stream) { nr_dlsch_qpsk_64qam_llr(frame_parms, @@ -920,7 +928,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pdsch_vars[eNB_id]->layer_llr[1], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128_2ndstream); } } @@ -933,7 +941,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho2_ext, pdsch_vars[eNB_id]->layer_llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128); if (rx_type==rx_IC_dual_stream) { nr_dlsch_16qam_64qam_llr(frame_parms, @@ -944,7 +952,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pdsch_vars[eNB_id]->layer_llr[1], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr128_2ndstream); } } @@ -957,7 +965,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho2_ext, (int16_t*)pllr_symbol_layer0, symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr_offset[symbol]); if (rx_type==rx_IC_dual_stream) { nr_dlsch_64qam_64qam_llr(frame_parms, @@ -968,7 +976,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], pllr_symbol_layer1, symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_tti_rx,symbol), + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol), pdsch_vars[eNB_id]->llr_offset[symbol]); } } @@ -981,7 +989,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } if (dlsch1_harq) { - switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) { + uint8_t Qm = nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table); + if (Qm == 0){ + LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n"); + return -1; + } + switch (Qm) { case 2 : if (rx_type==rx_standard) { nr_dlsch_qpsk_llr(frame_parms, @@ -1032,11 +1045,11 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif @@ -1045,30 +1058,30 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, char filename[40]; uint8_t aa = 0; - snprintf(filename, 40, "rxdataF0_symb_%d_nr_tti_rx_%d.m", symbol, nr_tti_rx); - write_output(filename, "rxdataF0", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); + snprintf(filename, 40, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); + write_output(filename, "rxdataF0", &common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); - snprintf(filename, 40, "dl_ch_estimates0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx); + snprintf(filename, 40, "dl_ch_estimates0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); write_output(filename, "dl_ch_estimates", &pdsch_vars[eNB_id]->dl_ch_estimates[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); - snprintf(filename, 40, "rxdataF_ext0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx); + snprintf(filename, 40, "rxdataF_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); write_output(filename, "rxdataF_ext", &pdsch_vars[eNB_id]->rxdataF_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); - snprintf(filename, 40, "dl_ch_estimates_ext0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx); + snprintf(filename, 40, "dl_ch_estimates_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); write_output(filename, "dl_ch_estimates_ext00", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); - snprintf(filename, 40, "rxdataF_comp0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx); + snprintf(filename, 40, "rxdataF_comp0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); write_output(filename, "rxdataF_comp00", &pdsch_vars[eNB_id]->rxdataF_comp0[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); for (int i=0; i < 2; i++){ - snprintf(filename, 40, "llr%d_symb_%d_nr_tti_rx_%d.m", i, symbol, nr_tti_rx); + snprintf(filename, 40, "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx); write_output(filename,"llr", &pdsch_vars[eNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm), 1, 0); } #endif #if T_TRACER T(T_UE_PHY_PDSCH_IQ, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(frame%1024), - T_INT(nr_tti_rx), T_INT(nb_rb), + T_INT(nr_slot_rx), T_INT(nb_rb), T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_slot), T_BUFFER(&pdsch_vars[eNB_id]->rxdataF_comp0[eNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_slot*2)); @@ -1797,6 +1810,7 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, NR_UE_DLSCH_t **dlsch_ue, uint8_t symbol, uint8_t pilots, + uint32_t len, unsigned short nb_rb) { @@ -1806,17 +1820,14 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, unsigned char aatx,aarx; __m128i *dl_ch128, ch_amp128; - - if (pilots==1){ - nb_rb = nb_rb>>1; - } + uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); // Determine scaling amplitude based the symbol ch_amp = 1024*8; //((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); - LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol); - // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); + LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol); + // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 @@ -1825,7 +1836,7 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; - for (rb=0;rbnushift ==0 || frame_parms->nushift == 1, - "nushift %d is illegal\n",frame_parms->nushift); + if (config_type==pdsch_dmrs_type1) + AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 1, + "nushift %d is illegal\n",frame_parms->nushift); + else + AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 2 || frame_parms->nushift == 4, + "nushift %d is illegal\n",frame_parms->nushift); for (aarx=0; aarxnb_antennas_rx; aarx++) { @@ -2388,34 +2404,44 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, if (k>frame_parms->ofdm_symbol_size) { k = k-frame_parms->ofdm_symbol_size; rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; - } + } if (pilots==0) { memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext)); dl_ch0_ext+=12; rxF_ext+=12; - } else { - j=0; - - for (i = (1-frame_parms->nushift); - i<12; - i+=2) { - rxF_ext[j]=rxF[i]; - dl_ch0_ext[j]=dl_ch0[i]; - j++; - } - - - dl_ch0_ext+=6; - rxF_ext+=6; + } else {//the symbol contains DMRS + j=0; + if (config_type==pdsch_dmrs_type1){ + for (i = (1-frame_parms->nushift); i<12; i+=2) { + rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+=6; + rxF_ext+=6; + } else { + for (i = (2+frame_parms->nushift); i<6; i++) { + rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + for (i = (8+frame_parms->nushift); i<12; i++) { + rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+= 8; + rxF_ext+= 8; + } } - + dl_ch0+=12; rxF+=12; k+=12; if (k>=frame_parms->ofdm_symbol_size) { - k=k-(frame_parms->ofdm_symbol_size); - rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; + k = k-(frame_parms->ofdm_symbol_size); + rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; } } } @@ -2434,7 +2460,7 @@ unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF, uint8_t pilots, unsigned short start_rb, unsigned short nb_rb_pdsch, - unsigned char nr_tti_rx, + unsigned char nr_slot_rx, uint32_t high_speed_flag, NR_DL_FRAME_PARMS *frame_parms, MIMO_mode_t mimo_mode) { @@ -2551,7 +2577,7 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw, #ifdef USER_MODE -void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t nr_tti_rx,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid) +void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t nr_slot_rx,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid) { unsigned int nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12; char fname[32],vname[32]; @@ -2559,50 +2585,50 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t nr_tti_rx,unsigned int * snprintf(fname, 32, "dlsch%d_rxF_r%d_ext0.m",eNB_id,round); snprintf(vname, 32, "dl%d_rxF_r%d_ext0",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1); if (ue->frame_parms.nb_antennas_rx >1) { snprintf(fname, 32, "dlsch%d_rxF_r%d_ext1.m",eNB_id,round); snprintf(vname, 32, "dl%d_rxF_r%d_ext1",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1); } snprintf(fname, 32, "dlsch%d_ch_r%d_ext00.m",eNB_id,round); snprintf(vname, 32, "dl%d_ch_r%d_ext00",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1); if (ue->transmission_mode[eNB_id]==7){ snprintf(fname, 32, "dlsch%d_bf_ch_r%d.m",eNB_id,round); snprintf(vname, 32, "dl%d_bf_ch_r%d",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1); //write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0],512,1,1); snprintf(fname, 32, "dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round); snprintf(vname, 32, "dl%d_bf_ch_r%d_ext00",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1); } if (ue->frame_parms.nb_antennas_rx == 2) { snprintf(fname, 32, "dlsch%d_ch_r%d_ext01.m",eNB_id,round); snprintf(vname, 32, "dl%d_ch_r%d_ext01",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1); } if (ue->frame_parms.nb_antenna_ports_gNB == 2) { snprintf(fname, 32, "dlsch%d_ch_r%d_ext10.m",eNB_id,round); snprintf(vname, 32, "dl%d_ch_r%d_ext10",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1); if (ue->frame_parms.nb_antennas_rx == 2) { snprintf(fname, 32, "dlsch%d_ch_r%d_ext11.m",eNB_id,round); snprintf(vname, 32, "dl%d_ch_r%d_ext11",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1); } } snprintf(fname, 32, "dlsch%d_rxF_r%d_uespec0.m",eNB_id,round); snprintf(vname, 32, "dl%d_rxF_r%d_uespec0",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1); /* write_output("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1); @@ -2612,31 +2638,31 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t nr_tti_rx,unsigned int * snprintf(fname, 32, "dlsch%d_r%d_rho.m",eNB_id,round); snprintf(vname, 32, "dl_rho_r%d_%d",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); snprintf(fname, 32, "dlsch%d_r%d_rho2.m",eNB_id,round); snprintf(vname, 32, "dl_rho2_r%d_%d",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1); snprintf(fname, 32, "dlsch%d_rxF_r%d_comp0.m",eNB_id,round); snprintf(vname, 32, "dl%d_rxF_r%d_comp0",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1); if (ue->frame_parms.nb_antenna_ports_gNB == 2) { snprintf(fname, 32, "dlsch%d_rxF_r%d_comp1.m",eNB_id,round); snprintf(vname, 32, "dl%d_rxF_r%d_comp1",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); } snprintf(fname, 32, "dlsch%d_rxF_r%d_llr.m",eNB_id,round); snprintf(vname, 32, "dl%d_r%d_llr",eNB_id,round); - write_output(fname,vname, ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0); + write_output(fname,vname, ue->pdsch_vars[proc->thread_id][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0); snprintf(fname, 32, "dlsch%d_r%d_mag1.m",eNB_id,round); snprintf(vname, 32, "dl%d_r%d_mag1",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1); snprintf(fname, 32, "dlsch%d_r%d_mag2.m",eNB_id,round); snprintf(vname, 32, "dl%d_r%d_mag2",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1); // printf("log2_maxh = %d\n",ue->pdsch_vars[eNB_id]->log2_maxh); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 5c480d6646..460dcfadb0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -131,7 +131,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini #endif // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf for(int i=pbch_initial_symbol; idlsch_channel_estimation_stats); #endif @@ -155,7 +155,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini #endif // computing channel estimation for selected best ssb for(int i=pbch_initial_symbol; ii_ssb,temp_ptr->n_hf); + nr_pbch_channel_estimation(ue,proc,0,0,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf); #if UE_TIMING_TRACE stop_meas(&ue->dlsch_channel_estimation_stats); #endif @@ -286,19 +286,17 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, for(int i=0; i<4;i++) nr_slot_fep_init_sync(ue, - i, - 0, - is*fp->samples_per_frame+ue->ssb_offset, - 0); + proc, + i, + 0, + is*fp->samples_per_frame+ue->ssb_offset, + 0); #ifdef DEBUG_INITIAL_SYNCH LOG_I(PHY,"Calling sss detection (normal CP)\n"); #endif - rx_sss_nr(ue,&metric_tdd_ncp,&phase_tdd_ncp); - - //FK: why do we need to do this again here? - //nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0); + rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp); nr_gold_pbch(ue); ret = nr_pbch_detection(proc, ue,1,mode); // start pbch detection at first symbol after pss @@ -321,8 +319,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, int nb_prefix_samples0 = fp->nb_prefix_samples0; fp->nb_prefix_samples0 = fp->nb_prefix_samples; - nr_slot_fep(ue,0, 0, ue->ssb_offset, 0, NR_PDCCH_EST); - nr_slot_fep(ue,1, 0, ue->ssb_offset, 0, NR_PDCCH_EST); + nr_slot_fep(ue, proc, 0, 0, ue->ssb_offset, 0, NR_PDCCH_EST); + nr_slot_fep(ue, proc, 1, 0, ue->ssb_offset, 0, NR_PDCCH_EST); fp->nb_prefix_samples0 = nb_prefix_samples0; LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n", diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 612dc6283d..813e737563 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -36,7 +36,7 @@ #include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/INIT/phy_init.h" -//#define DEBUG_PBCH 1 +//#define DEBUG_PBCH //#define DEBUG_PBCH_ENCODING #ifdef OPENAIR2 @@ -61,7 +61,8 @@ uint16_t nr_pbch_extract(int **rxdataF, int nushiftmod4 = frame_parms->nushift; unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; //and - if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size; + // if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size; + rx_offset=(rx_offset)%(frame_parms->ofdm_symbol_size); AssertFatal(symbol>=1 && symbol<5, "symbol %d illegal for PBCH extraction\n", @@ -103,8 +104,8 @@ uint16_t nr_pbch_extract(int **rxdataF, j++; } - //rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1); - rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1); + rx_offset=(rx_offset+1)%(frame_parms->ofdm_symbol_size); + //rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1); } rxF_ext+=9; @@ -126,12 +127,14 @@ uint16_t nr_pbch_extract(int **rxdataF, j++; } - //rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1); - rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1); + rx_offset=(rx_offset+1)%(frame_parms->ofdm_symbol_size); + //rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1); } rxF_ext+=9; - } else rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 12) : (rx_offset+12);//rx_offset = (rx_offset+12)&(frame_parms->ofdm_symbol_size-1); + } else{ //rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 12) : (rx_offset+12); + rx_offset = (rx_offset+12)%(frame_parms->ofdm_symbol_size); + } } } @@ -415,12 +418,11 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, NR_UE_PBCH *nr_ue_pbch_vars, NR_DL_FRAME_PARMS *frame_parms, - uint8_t eNB_id, + uint8_t gNB_id, uint8_t i_ssb, MIMO_mode_t mimo_mode, uint32_t high_speed_flag) { - int Ns = proc->nr_tti_rx; NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars; int max_h=0; int symbol; @@ -454,15 +456,15 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #ifdef DEBUG_PBCH - //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF); + //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF); write_output("rxdataF0_pbch.m","rxF0pbch", - &nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); + &nr_ue_common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); #endif // symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot for (symbol=1; symbol<4; symbol++) { - nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF, + nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, nr_ue_pbch_vars->dl_ch_estimates, nr_ue_pbch_vars->rxdataF_ext, nr_ue_pbch_vars->dl_ch_estimates_ext, @@ -606,11 +608,14 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, nr_downlink_indication_t dl_indication; fapi_nr_rx_indication_t rx_ind; - dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance - dl_indication.dci_ind = NULL; - dl_indication.proc=proc; - dl_indication.module_id=0; - dl_indication.cc_id=proc->CC_id; + dl_indication.module_id = ue->Mod_id; + dl_indication.gNB_index = gNB_id; + dl_indication.cc_id = proc->CC_id; + dl_indication.frame = proc->frame_rx; + dl_indication.slot = proc->nr_slot_rx; + dl_indication.thread_id = proc->thread_id; + dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance + dl_indication.dci_ind = NULL; rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_MIB; rx_ind.rx_indication_body[0].mib_pdu.pdu = &decoded_output[0]; //not good as it is pointing to a memory that can change diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 621f5ef806..465598d468 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -71,7 +71,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu; int32_t Xu_re, Xu_im; - int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k; + int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k, prachStartSymbol, sample_offset_slot; //int restricted_Type; prach = prach_tmp; @@ -94,7 +94,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ kbar = 1; K = 24; k = 12*n_ra_prb - 6*fp->N_RB_UL; - //prachStartSymbol = prach_config_pdu->prach_start_symbol + prachStartSymbol = prach_pdu->prach_start_symbol; //restricted_Type = 0; compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length, @@ -102,7 +102,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index, ue->X_u); - prach_start = fp->get_samples_slot_timestamp(slot, fp, 0); + sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1)); + prach_start = fp->get_samples_slot_timestamp(slot, fp, 0) + sample_offset_slot; // First compute physical root sequence /************************************************************************ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 845eace8b6..86e46402fd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -678,7 +678,7 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms, uint8_t *pmi_ext, uint32_t *rb_alloc, uint8_t symbol, - uint8_t subframe, + uint8_t nr_slot_rx, NR_DL_FRAME_PARMS *frame_parms) \brief This function extracts the received resource blocks, both channel estimates and data symbols, for the current allocation and for single antenna eNB transmission. @@ -690,23 +690,10 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms, @param pmi_ext Extracted PMI for chosen RBs @param rb_alloc RB allocation vector @param symbol Symbol to extract - @param subframe Subframe number - @param vrb_type Flag to indicate distributed VRB type + @param nr_slot_rx Slot number @param high_speed_flag @param frame_parms Pointer to frame descriptor */ -/*uint16_t nr_dlsch_extract_rbs_single(int32_t **rxdataF, - int32_t **dl_ch_estimates, - int32_t **rxdataF_ext, - int32_t **dl_ch_estimates_ext, - uint16_t pmi, - uint8_t *pmi_ext, - uint32_t *rb_alloc, - uint8_t symbol, - uint8_t subframe, - uint32_t high_speed_flag, - NR_DL_FRAME_PARMS *frame_parms);*/ - unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, int **dl_ch_estimates, int **rxdataF_ext, @@ -714,10 +701,11 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, unsigned short pmi, unsigned char *pmi_ext, unsigned char symbol, - uint8_t pilots, - unsigned short start_rb, - unsigned short nb_pdsch_rb, - unsigned char nr_tti_rx, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_pdsch_rb, + unsigned char nr_slot_rx, uint32_t high_speed_flag, NR_DL_FRAME_PARMS *frame_parms); @@ -740,7 +728,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, @param pmi_ext Extracted PMI for chosen RBs @param rb_alloc RB allocation vector @param symbol Symbol to extract - @param subframe Subframe index + @param nr_slot_rx Slot index @param high_speed_flag @param frame_parms Pointer to frame descriptor */ @@ -754,7 +742,7 @@ unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF, uint8_t pilots, unsigned short start_rb, unsigned short nb_rb_pdsch, - unsigned char nr_tti_rx, + unsigned char nr_slot_rx, uint32_t high_speed_flag, NR_DL_FRAME_PARMS *frame_parms, MIMO_mode_t mimo_mode); @@ -1002,7 +990,8 @@ void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, NR_UE_DLSCH_t **dlsch_ue, uint8_t symbol, - uint8_t start_symbol, + uint8_t start_symbol, + uint32_t len, uint16_t nb_rb); /** \brief This is the top-level entry point for DLSCH decoding in UE. It should be replicated on several @@ -1017,7 +1006,7 @@ void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext, @param lte_frame_parms Pointer to frame descriptor @param dlsch Pointer to DLSCH descriptor @param frame Frame number - @param subframe Subframe number + @param nr_slot_rx Slot number @param num_pdcch_symbols Number of PDCCH symbols @param is_crnti indicates if PDSCH belongs to a CRNTI (necessary for parallelizing decoding threads) @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used @@ -1025,13 +1014,15 @@ void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext, */ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, + UE_nr_rxtx_proc_t *proc, + int eNB_id, short *dlsch_llr, NR_DL_FRAME_PARMS *frame_parms, NR_UE_DLSCH_t *dlsch, NR_DL_UE_HARQ_t *harq_process, uint32_t frame, - uint16_t nb_symb_sch, - uint8_t nr_tti_rx, + uint16_t nb_symb_sch, + uint8_t nr_slot_rx, uint8_t harq_pid, uint8_t is_crnti, uint8_t llr8_flag); @@ -1081,7 +1072,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, - UE_nr_rxtx_proc_t *proc, + UE_nr_rxtx_proc_t *proc, int eNB_id, short *dlsch_llr, NR_DL_FRAME_PARMS *frame_parms, @@ -1089,7 +1080,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, NR_DL_UE_HARQ_t *harq_process, uint32_t frame, uint16_t nb_symb_sch, - uint8_t nr_tti_rx, + uint8_t nr_slot_rx, uint8_t harq_pid, uint8_t is_crnti, uint8_t llr8_flag); @@ -1111,8 +1102,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue, uint8_t eNB_id); int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, - uint32_t frame, - uint32_t slot); + UE_nr_rxtx_proc_t *proc); /*! \brief Extract PSS and SSS resource elements @@ -1452,25 +1442,31 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, runmode_t mode, int n_frames); +/*! + \brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the availability of the latter + @param fp Pointer to frame params + @param dl_Carrier Pointer to DL carrier to be set + @param ul_Carrier Pointer to UL carrier to be set +*/ +void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp, + uint64_t *dl_Carrier, + uint64_t *ul_Carrier); /*! - \brief Encoding of PUSCH/ACK/RI/ACK from 36-212. - @param a Pointer to ulsch SDU - @param frame_parms Pointer to Frame parameters - @param ulsch Pointer to ulsch descriptor - @param harq_pid HARQ process ID - @param tmode Transmission mode (1-7) - @param control_only_flag Generate PUSCH with control information only - @param Nbundled Parameter for ACK/NAK bundling (36.213 Section 7.3) + \brief This function sets the OAI RF card rx/tx params + @param openair0_cfg Pointer OAI config for a specific card + @param tx_gain_off Tx gain offset + @param rx_gain_off Rx gain offset + @param ul_Carrier UL carrier to be set + @param dl_Carrier DL carrier to be set + @param freq_offset Freq offset to be set */ -uint32_t ulsch_encoding(uint8_t *a, - PHY_VARS_NR_UE *phy_vars_ue, - uint8_t harq_pid, - uint8_t eNB_id, - uint8_t subframe_rx, - uint8_t tmode, - uint8_t control_only_flag, - uint8_t Nbundled); +void nr_rf_card_config(openair0_config_t *openair0_cfg, + double rx_gain_off, + uint64_t ul_Carrier, + uint64_t dl_Carrier, + int freq_offset); + void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL); @@ -1695,9 +1691,8 @@ uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset); uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, - int frame, - int slot, - fapi_nr_dci_indication_t *dci_ind); + UE_nr_rxtx_proc_t *proc, + fapi_nr_dci_indication_t *dci_ind); /** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation. It performs @@ -1712,36 +1707,25 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, @param eNB_id eNb index (Nid1) 0,1,2 @param eNB_id_i Interfering eNB index (Nid1) 0,1,2, or 3 in case of MU-MIMO IC receiver @param frame Frame number - @param nr_tti_rx Subframe number + @param nr_slot_rx Slot number @param symbol Symbol on which to act (within sub-frame) @param first_symbol_flag set to 1 on first DLSCH symbol @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice. @param i_mod Modulation order of the interfering stream */ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, PDSCH_t type, unsigned char eNB_id, unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference uint32_t frame, - uint8_t nr_tti_rx, + uint8_t nr_slot_rx, unsigned char symbol, unsigned char first_symbol_flag, RX_type_t rx_type, unsigned char i_mod, unsigned char harq_pid); -uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, - short *dlsch_llr, - NR_DL_FRAME_PARMS *frame_parms, - NR_UE_DLSCH_t *dlsch, - NR_DL_UE_HARQ_t *harq_process, - uint32_t frame, - uint16_t nb_symb_sch, - uint8_t nr_tti_rx, - uint8_t harq_pid, - uint8_t is_crnti, - uint8_t llr8_flag); - int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe); void *dlsch_thread(void *arg); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index d1dd0f785b..a3e202d4fe 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -139,6 +139,8 @@ typedef struct { uint32_t num_of_mod_symbols; // decode phich uint8_t decode_phich; + // Encoder BG + uint8_t BG; } NR_UL_UE_HARQ_t; typedef struct { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c new file mode 100644 index 0000000000..7cf64b28bb --- /dev/null +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c @@ -0,0 +1,90 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/NR_UE_TRANSPORT/nr_ue_rf_config.c +* \brief Functional helpers to configure the RF boards at UE side +* \author Guido Casati +* \date 2020 +* \version 0.1 +* \company Fraunhofer IIS +* \email: guido.casati@iis.fraunhofer.de +*/ + +#include "PHY/defs_nr_UE.h" +#include "PHY/phy_extern_nr_ue.h" +#include "nr_transport_proto_ue.h" + +void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp, uint64_t *dl_carrier, uint64_t *ul_carrier){ + + if (downlink_frequency[0][0]) + *dl_carrier = downlink_frequency[0][0]; + else + *dl_carrier = fp->dl_CarrierFreq; + + if (uplink_frequency_offset[0][0]) + *ul_carrier = *dl_carrier + uplink_frequency_offset[0][0]; + else + *ul_carrier = *dl_carrier + fp->ul_CarrierFreq - fp->dl_CarrierFreq; + +} + +void nr_rf_card_config(openair0_config_t *openair0_cfg, + double rx_gain_offset, + uint64_t ul_carrier, + uint64_t dl_carrier, + int freq_offset){ + + uint8_t mod_id = 0; + uint8_t cc_id = 0; + PHY_VARS_NR_UE *ue = PHY_vars_UE_g[mod_id][cc_id]; + int rf_chain = ue->rf_map.chain; + double rx_gain = ue->rx_total_gain_dB; + double tx_gain = ue->tx_total_gain_dB; + + for (int i = rf_chain; i < rf_chain + 4; i++) { + + if (i < openair0_cfg->rx_num_channels) + openair0_cfg->rx_freq[i + rf_chain] = dl_carrier + freq_offset; + else + openair0_cfg->rx_freq[i] = 0.0; + + if (itx_num_channels) + openair0_cfg->tx_freq[i] = ul_carrier + freq_offset; + else + openair0_cfg->tx_freq[i] = 0.0; + + if (tx_gain) + openair0_cfg->tx_gain[i] = tx_gain; + if (rx_gain) + openair0_cfg->rx_gain[i] = rx_gain - rx_gain_offset; + + openair0_cfg->autocal[i] = 1; + + LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n", + i, + rf_chain, + openair0_cfg->tx_gain[i], + openair0_cfg->rx_gain[i], + openair0_cfg->tx_freq[i], + openair0_cfg->rx_freq[i]); + + } +} \ No newline at end of file diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index ee10c96c20..fdd40feeba 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -232,7 +232,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, uint8_t mod_order; uint16_t Kr,r; uint32_t r_offset; - uint8_t BG; uint32_t E,Kb; uint8_t Ilbrm; uint32_t Tbslbrm; @@ -255,7 +254,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, R = nr_get_code_rate_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table); Kr=0; r_offset=0; - BG = 1; F=0; Ilbrm = 0; Tbslbrm = 950984; //max tbs @@ -327,10 +325,10 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, Coderate = (float) R /(float) 2048; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ - BG = 2; + harq_process->BG = 2; } else{ - BG = 1; + harq_process->BG = 1; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN); @@ -341,7 +339,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, &harq_process->K, pz, &harq_process->F, - BG); + harq_process->BG); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT); F = harq_process->F; @@ -390,17 +388,20 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, } printf("\n");*/ encoder_implemparams_t impp; - impp.n_segments=harq_process->C; - impp.macro_num=0; - impp.tinput = NULL; - impp.tprep = NULL; - impp.tparity = NULL; - impp.toutput = NULL; + impp.n_segments = harq_process->C; + impp.tinput = NULL; + impp.tprep = NULL; + impp.tparity = NULL; + impp.toutput = NULL; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN); - - nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,&impp); - + + for(int j = 0; j < (harq_process->C/8 + 1); j++) + { + impp.macro_num = j; + nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,harq_process->BG,&impp); + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT); //stop_meas(te_stats); @@ -448,7 +449,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN); nr_rate_matching_ldpc(Ilbrm, Tbslbrm, - BG, + harq_process->BG, *pz, harq_process->d[r], harq_process->e+r_offset, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index ea79fd467f..61e39aa79d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -360,7 +360,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ptrs_idx++; - } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, cdm_grps_no_data, dmrs_type)) { + } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index cf0fc716f9..4ac1c47b02 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -560,7 +560,6 @@ void set_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change { /* set new value according to rate_change */ frame_parms_ue->ofdm_symbol_size = (frame_parms_ue->ofdm_symbol_size / rate_change); - frame_parms_ue->samples_per_tti = (frame_parms_ue->samples_per_tti / rate_change); frame_parms_ue->samples_per_subframe = (frame_parms_ue->samples_per_subframe / rate_change); free_context_pss_nr(); @@ -588,7 +587,6 @@ void set_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change void restore_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change) { frame_parms_ue->ofdm_symbol_size = frame_parms_ue->ofdm_symbol_size * rate_change; - frame_parms_ue->samples_per_tti = frame_parms_ue->samples_per_tti * rate_change; frame_parms_ue->samples_per_subframe = frame_parms_ue->samples_per_subframe * rate_change; free_context_pss_nr(); @@ -620,8 +618,6 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); int samples_for_frame = 2*frame_parms->samples_per_frame; - AssertFatal(frame_parms->samples_per_tti > 3839,"Illegal samples_per_tti %d\n",frame_parms->samples_per_tti); - #if TEST_SYNCHRO_TIMING_PSS opp_enabled = 1; diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 0b8111fc32..3560b23550 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -57,14 +57,14 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, long pucch_GroupHopping, long hoppingId, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t m0, uint8_t mcs, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint16_t startingPRB) { #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch0] start function at slot(nr_tti_tx)=%d\n",nr_tti_tx); + printf("\t [nr_generate_pucch0] start function at slot(nr_slot_tx)=%d\n",nr_slot_tx); #endif /* * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation @@ -112,8 +112,8 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, for (int l=0; l= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", - n_hop,nr_tti_tx); + printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_slot_tx=%d\n", + n_hop,nr_slot_tx); #endif - nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,lprime,nr_tti_tx); + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_slot_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,lprime,nr_slot_tx); for (int n=0; n<12; n++) { r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) @@ -505,7 +505,7 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t m0, uint8_t nrofSymbols, uint8_t startingSymbolIndex, @@ -514,8 +514,8 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, uint8_t timeDomainOCC, uint8_t nr_bit) { #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", - nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); + printf("\t [nr_generate_pucch1] start function at slot(nr_slot_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", + nr_slot_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); #endif /* * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation @@ -603,11 +603,11 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, // y_n contains the complex value d multiplied by the sequence r_u_v int16_t y_n_re[12],y_n_im[12]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", - n_hop,nr_tti_tx); + printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_slot_tx=%d\n", + n_hop,nr_slot_tx); #endif - nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,lnormal,lprime,nr_tti_tx); + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_slot_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,lnormal,lprime,nr_slot_tx); for (int n=0; n<12; n++) { r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) @@ -806,7 +806,7 @@ inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id, int i; uint8_t c; // c_init=nRNTI*2^15+n_id according to TS 38.211 Subclause 6.3.2.6.1 - //x2 = (rnti) + ((uint32_t)(1+nr_tti_tx)<<16)*(1+(fp->Nid_cell<<1)); + //x2 = (rnti) + ((uint32_t)(1+nr_slot_tx)<<16)*(1+(fp->Nid_cell<<1)); x2 = ((rnti)<<15)+n_id; #ifdef DEBUG_NR_PUCCH_TX printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x, M_bit %d\n",s,M_bit); @@ -960,14 +960,14 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint8_t nrofPRB, uint16_t startingPRB, uint8_t nr_bit) { #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch2] start function at slot(nr_tti_tx)=%d with payload=%lu and nr_bit=%d\n",nr_tti_tx, payload, nr_bit); + printf("\t [nr_generate_pucch2] start function at slot(nr_slot_tx)=%d with payload=%lu and nr_bit=%d\n",nr_slot_tx, payload, nr_bit); #endif // b is the block of bits transmitted on the physical channel after payload coding uint64_t b[16]; // limit to 1024-bit encoded length @@ -1043,9 +1043,13 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, int m=0; for (int l=0; l>2); ii++) { + s = lte_gold_generic(&x1, &x2, reset); + reset = 0; + } m = 0; for (int rb=0; rb= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop - nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_slot_tx,&u,&v); // calculating u and v value // Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33 if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies @@ -1497,7 +1501,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, } uint16_t j=0; - alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_tti_tx); + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_slot_tx); for (int rb=0; rbframe_tx; - int slot_number = proc->nr_tti_tx; + int slot_number = proc->nr_slot_tx; uint16_t n_SRS, n_SRS_cs_i; double alpha_i; uint8_t K_TC_p; @@ -278,7 +278,7 @@ int32_t generate_srs_nr(SRS_ResourceSet_t *p_srs_resource_set, n_SRS = l/R; } else { - int8_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * frame_parms->ttis_per_subframe; + int8_t N_slot_frame = frame_parms->slots_per_frame; n_SRS = ((N_slot_frame*frame_number + slot_number - T_offset)/T_SRS)*(N_symb_SRS/R)+(l/R); } @@ -399,7 +399,7 @@ int is_srs_period_nr(SRS_Resource_t *p_SRS_Resource, NR_DL_FRAME_PARMS *frame_pa return (-1); } - int16_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * frame_parms->ttis_per_subframe; + int16_t N_slot_frame = frame_parms->slots_per_frame; if ((N_slot_frame*frame_tx + slot_tx - T_offset)%T_SRS == 0) { return (0); } @@ -445,7 +445,7 @@ int ue_srs_procedure_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB /* SRS resource configurated ? */ if (p_srs_resource != NULL) { if (p_srs_resource_set->resourceType == periodic) { - if (is_srs_period_nr(p_srs_resource, frame_parms, proc->frame_tx, proc->nr_tti_tx) == 0) { + if (is_srs_period_nr(p_srs_resource, frame_parms, proc->frame_tx, proc->nr_slot_tx) == 0) { generate_srs = 1; } } @@ -459,7 +459,7 @@ int ue_srs_procedure_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB if (generate_srs == 1) { int16_t txptr = AMP; uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12; - uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((proc->nr_tti_tx*nsymb)+(nsymb-1)); + uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((proc->nr_slot_tx*nsymb)+(nsymb-1)); if (generate_srs_nr(p_srs_resource_set, frame_parms, &ue->common_vars.txdataF[eNB_id][symbol_offset], txptr, proc) == 0) { return 0; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index e3f1f13a8d..66296910fc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -314,6 +314,7 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue, *********************************************************************/ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], uint8_t doPss, uint8_t doSss, @@ -331,7 +332,7 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, pss_symbol = 0; sss_symbol = SSS_SYMBOL_NB-PSS_SYMBOL_NB; - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size; @@ -386,7 +387,7 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, /******************************************************************* * -* NAME : rx_sss_nr +* NAME : pss_sss_extract_nr * * PARAMETERS : none * @@ -397,11 +398,12 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, *********************************************************************/ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue, + UE_nr_rxtx_proc_t *proc, int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], uint8_t subframe) { - return do_pss_sss_extract_nr(phy_vars_ue, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe); + return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe); } /******************************************************************* @@ -417,7 +419,7 @@ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue, * *********************************************************************/ -int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) +int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max) { uint8_t i; int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR]; @@ -433,6 +435,7 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) // pss sss extraction pss_sss_extract_nr(ue, + proc, pss_ext, sss_ext, 0); /* subframe */ @@ -440,8 +443,8 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) #ifdef DEBUG_PLOT_SSS write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_subframe,1,1); - write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[0]].rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1); - write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[0]].rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1); + write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1); #endif diff --git a/openair1/PHY/TOOLS/lte_enb_scope.c b/openair1/PHY/TOOLS/lte_enb_scope.c index b2c6bd909f..19e135ae56 100644 --- a/openair1/PHY/TOOLS/lte_enb_scope.c +++ b/openair1/PHY/TOOLS/lte_enb_scope.c @@ -97,7 +97,7 @@ static void *scope_thread_eNB(void *arg) { } } - sleep(1); + usleep(100*1000); } // printf("%s",stats_buffer); diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 8621898d9d..acd22bc78d 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -37,9 +37,12 @@ float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; float tput_ue_max[NUMBER_OF_UE_MAX] = {0}; -static void ia_receiver_on_off( FL_OBJECT *button, long arg) -{ +void drawsymbol(FL_OBJECT *obj, int id, + FL_POINT *p, int n, int w, int h) { + fl_points( p, n, FL_YELLOW); +} +static void ia_receiver_on_off( FL_OBJECT *button, long arg) { if (fl_get_button(button)) { fl_set_object_label(button, "IA Receiver ON"); // PHY_vars_UE_g[0][0]->use_ia_receiver = 1; @@ -51,9 +54,7 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg) } } -static void dl_traffic_on_off( FL_OBJECT *button, long arg) -{ - +static void dl_traffic_on_off( FL_OBJECT *button, long arg) { if (fl_get_button(button)) { fl_set_object_label(button, "DL Traffic ON"); otg_enabled = 1; @@ -65,46 +66,38 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg) } } -FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) -{ - +FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) { FL_OBJECT *obj; FD_lte_phy_scope_enb *fdui = fl_malloc( sizeof *fdui ); - // Define form fdui->lte_phy_scope_enb = fl_bgn_form( FL_NO_BOX, 800, 800 ); - // This the whole UI box obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" ); fl_set_object_color( obj, FL_BLACK, FL_BLACK ); - // Received signal fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" ); fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color fl_set_xyplot_ybounds(fdui->rxsig_t,10,70); - // Time-domain channel response fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "SRS Frequency Response (samples, abs)" ); fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color - // Frequency-domain channel response fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" ); fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color fl_set_xyplot_ybounds( fdui->chest_f,30,70); - // LLR of PUSCH fdui->pusch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)" ); fl_set_object_boxtype( fdui->pusch_llr, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pusch_llr, FL_BLACK, FL_YELLOW ); fl_set_object_lcolor( fdui->pusch_llr, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pusch_llr,2); - + fl_set_xyplot_symbol(fdui->pusch_llr, 0, drawsymbol); // I/Q PUSCH comp fdui->pusch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 200, "PUSCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pusch_comp, FL_EMBOSSED_BOX ); @@ -112,7 +105,7 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) fl_set_object_lcolor( fdui->pusch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pusch_comp,2); fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR); - + fl_set_xyplot_symbol(fdui->pusch_comp, 0, drawsymbol); // I/Q PUCCH comp (format 1) fdui->pucch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 480, 240, 100, "PUCCH1 Energy (SR)" ); fl_set_object_boxtype( fdui->pucch_comp1, FL_EMBOSSED_BOX ); @@ -120,7 +113,7 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) fl_set_object_lcolor( fdui->pucch_comp1, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pucch_comp1,2); // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR); - + fl_set_xyplot_symbol(fdui->pucch_comp1, 0, drawsymbol); // I/Q PUCCH comp (fromat 1a/b) fdui->pucch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 600, 240, 100, "PUCCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pucch_comp, FL_EMBOSSED_BOX ); @@ -128,13 +121,12 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) fl_set_object_lcolor( fdui->pucch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pucch_comp,2); // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR); - + fl_set_xyplot_symbol(fdui->pucch_comp, 0, drawsymbol); // Throughput on PUSCH fdui->pusch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 480, 500, 100, "PUSCH Throughput [frame]/[kbit/s]" ); fl_set_object_boxtype( fdui->pusch_tput, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pusch_tput, FL_BLACK, FL_WHITE ); fl_set_object_lcolor( fdui->pusch_tput, FL_WHITE ); // Label color - // Generic eNB Button fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" ); fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER ); @@ -143,18 +135,15 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) fl_set_object_label(fdui->button_0, "DL Traffic OFF"); fl_set_object_color(fdui->button_0, FL_RED, FL_RED); fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 ); - fl_end_form( ); fdui->lte_phy_scope_enb->fdui = fdui; - return fdui; } void phy_scope_eNB(FD_lte_phy_scope_enb *form, PHY_VARS_eNB *phy_vars_enb, - int UE_id) -{ - + int UE_id) { + LOG_D(HW,"scope for UE%d\n", UE_id); int i,i2,arx,atx,ind,k; LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_enb->frame_parms; int nsymb_ce = 12*frame_parms->N_RB_UL*frame_parms->symbols_per_tti; @@ -192,20 +181,18 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, } coded_bits_per_codeword = frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti; - - chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); - llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero + chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); + llr = (float *) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero bit = malloc(coded_bits_per_codeword*sizeof(float)); rxsig_t = (int16_t**) phy_vars_enb->RU_list[0]->common.rxdata; - //chest_t = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id]; - chest_t = (int16_t**) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates; - chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates; - pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr; - pusch_comp = (int32_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; - pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id]; - pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id]; - pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id]; + chest_t = (int16_t **) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates; + chest_f = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates; + pusch_llr = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->llr; + pusch_comp = (int32_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; + pucch1_comp = (int32_t *) phy_vars_enb->pucch1_stats[UE_id]; + pucch1_thres = (int32_t *) phy_vars_enb->pucch1_stats_thres[UE_id]; + pucch1ab_comp = (int32_t *) phy_vars_enb->pucch1ab_stats[UE_id]; // Received signal in time domain of receive antenna 0 if (rxsig_t != NULL) { @@ -236,7 +223,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, if (chest_t[0] !=NULL) { for (i=0; i<(frame_parms->ofdm_symbol_size); i++) { //i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size; - i2=i; + i2=i; //time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1)); time2[i] = (float)i; chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1])); @@ -278,7 +265,6 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, freq[ind] = (float)ind; Re = (float)(chest_f[(atx<<1)+arx][(2*k)]); Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]); - chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im)); ind++; } @@ -333,9 +319,9 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i] < range && pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1] > -range && pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1] < range ) { - I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i]; - Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1]; - ind++; + I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i]; + Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1]; + ind++; } } } @@ -346,75 +332,62 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, // PUSCH I/Q of MF Output if (pucch1ab_comp!=NULL) { for (ind=0; ind<10240; ind++) { - I_pucch[ind] = (float)pucch1ab_comp[2*(ind)]; Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1]; A_pucch[ind] = 10*log10(pucch1_comp[ind]); B_pucch[ind] = ind; C_pucch[ind] = (float)pucch1_thres[ind]; } + fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","",""); fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","",""); fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED); fl_set_xyplot_ybounds(form->pucch_comp,-5000,5000); fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000); - fl_set_xyplot_ybounds(form->pucch_comp1,0,80); } - // PUSCH Throughput memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); - tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame; tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0; - fl_set_xyplot_data(form->pusch_tput,tput_time_enb[UE_id],tput_enb[UE_id],TPUT_WINDOW_LENGTH,"","",""); - // fl_get_xyplot_ybounds(form->pusch_tput,&ymin,&ymax); // fl_set_xyplot_ybounds(form->pusch_tput,0,ymax); - fl_check_forms(); - free(llr); free(bit); free(chest_f_abs); } -FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) -{ - +FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) { FL_OBJECT *obj; FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui ); - // Define form fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 900 ); - // This the whole UI box obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 900, "" ); fl_set_object_color( obj, FL_BLACK, FL_BLACK ); - // Received signal fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" ); fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color fl_set_xyplot_ybounds(fdui->rxsig_t,10,70); - + fl_set_xyplot_symbol(fdui->rxsig_t, 0, drawsymbol); // Time-domain channel response fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" ); fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color - + fl_set_xyplot_symbol(fdui->chest_t, 0, drawsymbol); // Frequency-domain channel response fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" ); fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color fl_set_xyplot_ybounds( fdui->chest_f,30,70); - // LLR of PBCH fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" ); fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX ); @@ -423,23 +396,23 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) fl_set_xyplot_symbolsize( fdui->pbch_llr,2); fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR); fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920); - + fl_set_xyplot_symbol(fdui->pbch_llr, 0, drawsymbol); // I/Q PBCH comp fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN ); fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pbch_comp,2); + fl_set_xyplot_symbol(fdui->pbch_comp, 0, drawsymbol); // fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100); // fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100); - // LLR of PDCCH fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" ); fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN ); fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pdcch_llr,2); - + fl_set_xyplot_symbol(fdui->pdcch_llr, 0, drawsymbol); // I/Q PDCCH comp fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX ); @@ -447,7 +420,7 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pdcch_comp,2); fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR); - + fl_set_xyplot_symbol(fdui->pdcch_comp, 0, drawsymbol); // LLR of PDSCH fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX ); @@ -455,20 +428,19 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pdsch_llr,2); fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR); - + fl_set_xyplot_symbol(fdui->pdsch_llr, 0, drawsymbol); // I/Q PDSCH comp fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500, 240, 200, "PDSCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW ); fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pdsch_comp,2); - + fl_set_xyplot_symbol(fdui->pdsch_comp, 0, drawsymbol); // Throughput on PDSCH fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" ); fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE ); fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color - // Generic UE Button fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" ); fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER ); @@ -478,10 +450,8 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) fl_set_object_color(fdui->button_0, FL_RED, FL_RED); fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 ); fl_hide_object(fdui->button_0); - fl_end_form( ); fdui->lte_phy_scope_ue->fdui = fdui; - return fdui; } @@ -489,8 +459,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, PHY_VARS_UE *phy_vars_ue, int eNB_id, int UE_id, - uint8_t subframe) -{ + uint8_t subframe) { int i,arx,atx,ind,k; LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; int nsymb_ce = frame_parms->ofdm_symbol_size;//*frame_parms->symbols_per_tti; @@ -521,7 +490,6 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, unsigned char harq_pid = 0; int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; - if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) { harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid; @@ -556,34 +524,32 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); } - I = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float)); - Q = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float)); - chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*)); + I = (float *) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float)); + Q = (float *) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float)); + chest_t_abs = (float **) malloc(nb_antennas_rx*sizeof(float *)); for (arx=0; arxofdm_symbol_size,sizeof(float)); + chest_t_abs[arx] = (float *) calloc(frame_parms->ofdm_symbol_size,sizeof(float)); } - chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); + chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); //llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error. - llr = (float*) malloc(coded_bits_per_codeword*sizeof(float)); + llr = (float *) malloc(coded_bits_per_codeword*sizeof(float)); memset((void *)llr, 0,coded_bits_per_codeword*sizeof(float)); // init to zero - bit = malloc(coded_bits_per_codeword*sizeof(float)); - llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero - bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); - - rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata; - chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id]; - chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id]; - pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr; - pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; - pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr; - pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0]; - pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0 + llr_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero + bit_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); + rxsig_t = (int16_t **) phy_vars_ue->common_vars.rxdata; + chest_t = (int16_t **) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id]; + chest_f = (int16_t **) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id]; + pbch_llr = (int8_t *) phy_vars_ue->pbch_vars[eNB_id]->llr; + pbch_comp = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; + pdcch_llr = (int8_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr; + pdcch_comp = (int16_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0]; + pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0 //pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0 - pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0]; - pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0]; + pdsch_comp = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0]; + pdsch_mag = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0]; // Received signal in time domain of receive antenna 0 if (rxsig_t != NULL) { @@ -652,7 +618,6 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, freq[ind] = (float)ind; Re = (float)(chest_f[(atx<<1)+arx][(2*k)]); Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]); - chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im)); ind++; } @@ -715,13 +680,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3); - if (frame_parms->N_RB_DL != 100) - { - fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); - } - else - { - LOG_D(PHY,"UE PDCCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n"); + + if (frame_parms->N_RB_DL != 100) { + fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); + } else { + LOG_D(PHY,"UE PDCCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n"); } } @@ -731,13 +694,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, I[i] = pdcch_comp[2*i]; Q[i] = pdcch_comp[2*i+1]; } - if (frame_parms->N_RB_DL != 100) - { - fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); - } - else - { - LOG_D(PHY,"UE PDCCH COMP plot is bugged in 20 MHz BW, to be fixed !!!\n"); + + if (frame_parms->N_RB_DL != 100) { + fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); + } else { + LOG_D(PHY,"UE PDCCH COMP plot is bugged in 20 MHz BW, to be fixed !!!\n"); } } @@ -749,13 +710,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword); - if (frame_parms->N_RB_DL != 100) - { - fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","",""); - } - else - { - LOG_D(PHY,"UE PDSCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n"); + + if (frame_parms->N_RB_DL != 100) { + fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","",""); + } else { + LOG_D(PHY,"UE PDSCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n"); } } @@ -765,7 +724,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, for (k=0; ksymbols_per_tti; k++) { for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { - int j = (2*frame_parms->N_RB_DL*12*k)+4*i; + int j = (2*frame_parms->N_RB_DL*12*k)+4*i; I[ind] = (pdsch_mag[j ]!=0? 1.0/pdsch_mag[j ]: 0.0) * pdsch_comp[j ]*1.0; Q[ind] = (pdsch_mag[j+1]!=0? 1.0/pdsch_mag[j+1]: 0.0) * pdsch_comp[j+1]*1.0; ind++; @@ -778,7 +737,6 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, // PDSCH Throughput memmove( tput_time_ue[UE_id], &tput_time_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); memmove( tput_ue[UE_id], &tput_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); - tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame; tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0; @@ -787,11 +745,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","",""); - fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]); - fl_check_forms(); - free(I); free(Q); free(chest_f_abs); diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h index 1f8c0b8eee..cc3ec94a95 100644 --- a/openair1/PHY/defs_L1_NB_IoT.h +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -32,7 +32,9 @@ #ifndef __PHY_DEFS_NB_IOT__H__ #define __PHY_DEFS_NB_IOT__H__ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 15300426f3..b465a51a2a 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -624,6 +624,8 @@ typedef struct RU_t_s { int wakeup_L1_sleep_cnt_max; /// DL IF frequency in Hz uint64_t if_frequency; + /// UL IF frequency offset to DL IF frequency in Hz + int if_freq_offset; } RU_t; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 4d5a46c4fd..b6ffd06c2b 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -110,6 +110,8 @@ typedef struct { uint32_t K; /// Number of "Filler" bits uint32_t F; + /// Encoder BG + uint8_t BG; } NR_DL_gNB_HARQ_t; typedef struct { @@ -752,6 +754,9 @@ typedef struct PHY_VARS_gNB_s { uint32_t rb_mask_ul[9]; int ulmask_symb; + /// CSI RS sequence + uint32_t ***nr_gold_csi_rs; + /// Indicator set to 0 after first SR uint8_t first_sr[NUMBER_OF_NR_SR_MAX]; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index fff6a82047..8d31eb15f6 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -848,9 +848,6 @@ typedef struct { /// UE FAPI indication for DCI reception //fapi_nr_dci_indication_t dci_ind; - // point to the current rxTx thread index - uint8_t current_thread_id[NR_MAX_SLOTS_PER_FRAME]; - t_nrPolar_params *polarList; NR_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; @@ -1121,6 +1118,8 @@ typedef struct { SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; #endif + + int dl_stats[5]; } PHY_VARS_NR_UE; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index a21af3fa03..e5678f894d 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -82,6 +82,9 @@ #define NR_MAX_PDSCH_DMRS_LENGTH 3300 //275*6(k)*2(QPSK real+imag) #define NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD 104 // ceil(NR_MAX_PDSCH_DMRS_LENGTH/32) +#define NR_MAX_CSI_RS_LENGTH 4400 //275*8(max allocation per RB)*2(QPSK) +#define NR_MAX_CSI_RS_INIT_LENGTH_DWORD 138 // ceil(NR_MAX_CSI_RS_LENGTH/32) + #define NR_MAX_PUSCH_DMRS_LENGTH NR_MAX_PDSCH_DMRS_LENGTH #define NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD @@ -233,6 +236,7 @@ typedef struct { typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; typedef uint32_t (*get_samples_per_slot_t)(int slot, NR_DL_FRAME_PARMS* fp); +typedef uint32_t (*get_slot_from_timestamp_t)(openair0_timestamp timestamp_rx, NR_DL_FRAME_PARMS* fp); typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, NR_DL_FRAME_PARMS* fp, uint8_t sl_ahead); @@ -289,14 +293,14 @@ struct NR_DL_FRAME_PARMS { uint32_t samples_per_subframe; /// Number of samples in current slot get_samples_per_slot_t get_samples_per_slot; + /// slot calculation from timestamp + get_slot_from_timestamp_t get_slot_from_timestamp; /// Number of samples before slot get_samples_slot_timestamp_t get_samples_slot_timestamp; /// Number of samples in 0th and center slot of a subframe uint32_t samples_per_slot0; /// Number of samples in other slots of the subframe uint32_t samples_per_slotN0; - /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) - uint16_t symbols_per_tti; /// Number of samples in a radio frame uint32_t samples_per_frame; /// Number of samples in a subframe without CP @@ -305,15 +309,8 @@ struct NR_DL_FRAME_PARMS { uint32_t samples_per_slot_wCP; /// Number of samples in a radio frame without CP uint32_t samples_per_frame_wCP; - /// Number of samples in a tti (same as subrame in LTE, slot in NR) - uint32_t samples_per_tti; /// NR numerology index [0..5] as specified in 38.211 Section 4 (mu). 0=15khZ SCS, 1=30khZ, 2=60kHz, etc uint8_t numerology_index; - /// NR number of ttis per subframe deduced from numerology (cf 38.211): 1, 2, 4, 8(not supported),16(not supported),32(not supported) - uint8_t ttis_per_subframe; - /// NR number of slots per tti . Assumption only 2 Slot per TTI is supported (Slot Config 1 in 38.211) - uint8_t slots_per_tti; -//#endif /// Number of Physical transmit antennas in node uint8_t nb_antennas_tx; /// Number of Receive antennas in node diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 3e09f3f593..9d6f1703e5 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -496,8 +496,8 @@ typedef struct{ // CSI-MeasConfig IE is used to configure CSI-RS (reference sign uint8_t reportTriggerSize; } csi_MeasConfig_t; typedef enum { - pdsch_dmrs_type1 = 1, - pdsch_dmrs_type2 = 2 + pdsch_dmrs_type1 = 0, + pdsch_dmrs_type2 = 1 } pdsch_dmrs_type_t; typedef enum { pusch_dmrs_type1 = 0, diff --git a/openair1/PHY/phy_extern_nr_ue.h b/openair1/PHY/phy_extern_nr_ue.h index 2f2a0427f4..e06b0c913a 100644 --- a/openair1/PHY/phy_extern_nr_ue.h +++ b/openair1/PHY/phy_extern_nr_ue.h @@ -32,7 +32,8 @@ extern char fmageren_name2[512]; extern unsigned int RX_DMA_BUFFER[4][NB_ANTENNAS_RX]; extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX]; -//#include "PHY/LTE_TRANSPORT/transport_extern.h" +extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; +extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; extern const short conjugate[8],conjugate2[8]; extern int number_of_cards; diff --git a/openair1/PHY/thread_NR_UE.h b/openair1/PHY/thread_NR_UE.h index 94271ed55d..901d8faec9 100644 --- a/openair1/PHY/thread_NR_UE.h +++ b/openair1/PHY/thread_NR_UE.h @@ -4,26 +4,18 @@ #include /// Context data structure for RX/TX portion of subframe processing typedef struct { - /// index of the current UE RX/TX proc - int proc_id; + /// index of the current UE RX/TX thread + int thread_id; /// Component Carrier index uint8_t CC_id; /// timestamp transmitted to HW openair0_timestamp timestamp_tx; //#ifdef UE_NR_PHY_DEMO - /// NR TTI index within subframe_tx [0 .. ttis_per_subframe - 1] to act upon for transmission - int nr_tti_tx; - /// NR TTI index within subframe_rx [0 .. ttis_per_subframe - 1] to act upon for reception - int nr_tti_rx; /// NR slot index within frame_tx [0 .. slots_per_frame - 1] to act upon for transmission int nr_slot_tx; /// NR slot index within frame_rx [0 .. slots_per_frame - 1] to act upon for transmission int nr_slot_rx; //#endif - /// subframe to act upon for transmission - int subframe_tx; - /// subframe to act upon for reception - int subframe_rx; /// frame to act upon for transmission int frame_tx; /// frame to act upon for reception diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 9723b2f99e..a78b1f4805 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -89,13 +89,6 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { if (fp->numerology_index != 0) { if (!(slot%(fp->slots_per_subframe/2))&&(first_symbol==0)) { // case where first symbol in slot has longer prefix - apply_nr_rotation(fp, - (int16_t*)&ru->common.txdataF_BF[aa][slot_offsetF], - slot, - 0, - 1, - fp->ofdm_symbol_size); - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], (int*)&ru->common.txdata[aa][slot_offset], fp->ofdm_symbol_size, @@ -103,13 +96,6 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { fp->nb_prefix_samples0, CYCLIC_PREFIX); - apply_nr_rotation(fp, - (int16_t*)&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size], - slot, - 1, - num_symbols-1, - fp->ofdm_symbol_size); - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size], (int*)&ru->common.txdata[aa][slot_offset+fp->nb_prefix_samples0+fp->ofdm_symbol_size], fp->ofdm_symbol_size, @@ -118,12 +104,6 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { CYCLIC_PREFIX); } else { // all symbols in slot have shorter prefix - apply_nr_rotation(fp, - (int16_t*)&ru->common.txdataF_BF[aa][slot_offsetF], - slot, - first_symbol, - num_symbols, - fp->ofdm_symbol_size); PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], (int*)&ru->common.txdata[aa][slot_offset], fp->ofdm_symbol_size, @@ -141,12 +121,6 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { 1, fp->nb_prefix_samples, CYCLIC_PREFIX); - apply_nr_rotation(fp, - (int16_t*)&ru->common.txdata[aa][slot_offset], - slot, - idx_sym, - 1, - fp->ofdm_symbol_size+fp->nb_prefix_samples); slot_offset += fp->nb_prefix_samples+fp->ofdm_symbol_size; } else { @@ -156,12 +130,6 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { 1, fp->nb_prefix_samples0, CYCLIC_PREFIX); - apply_nr_rotation(fp, - (int16_t*)&ru->common.txdata[aa][slot_offset], - slot, - 0, - 1, - fp->ofdm_symbol_size+fp->nb_prefix_samples0); slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size; } } diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c index 9d34f496b3..3864b2fcb2 100644 --- a/openair1/SCHED_NR/phy_frame_config_nr.c +++ b/openair1/SCHED_NR/phy_frame_config_nr.c @@ -252,7 +252,7 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) { while(p_current_TDD_UL_DL_SlotConfig != NULL) { int slot_index = p_current_TDD_UL_DL_SlotConfig->slotIndex; - if (slot_index < TDD_CONFIG_NB_FRAMES*(frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME)) { + if (slot_index < TDD_CONFIG_NB_FRAMES * frame_parms->slots_per_frame) { if (p_current_TDD_UL_DL_SlotConfig->nrofDownlinkSymbols != 0) { if (p_current_TDD_UL_DL_SlotConfig->nrofDownlinkSymbols == NR_TDD_SET_ALL_SYMBOLS) { if (p_current_TDD_UL_DL_SlotConfig->nrofUplinkSymbols == 0) { @@ -308,7 +308,7 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) { * *********************************************************************/ -int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) { +int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot) { /* for FFD all slot can be considered as an uplink */ int mu = cfg->ssb_config.scs_common.value,check_slot=0; @@ -318,7 +318,7 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) if (nr_frame%2 == 0) { for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) { + if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) { check_slot++; } } @@ -330,7 +330,7 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) check_slot = 0; for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) { + if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) { check_slot++; } } @@ -342,7 +342,7 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) } } else { for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); else nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); - + + if (T_ACTIVE(T_GNB_PHY_MIB)) { + unsigned char bch[3]; + bch[0] = gNB->ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff; + bch[1] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff; + bch[2] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff; + T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3)); + } + nr_generate_pbch(&gNB->pbch, &gNB->ssb_pdu, gNB->nr_pbch_interleaver, @@ -136,8 +144,6 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int offset = gNB->CC_id; uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP; - - if (cfg->ssb_table.ssb_period.value > 1) ssb_frame_periodicity = 1 <<(cfg->ssb_table.ssb_period.value -1) ; @@ -199,6 +205,10 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); } + + //apply the OFDM symbol rotation here + apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[0][txdataF_offset],slot,0,fp->Ncp==EXTENDED?12:14,fp->ofdm_symbol_size); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0); } @@ -247,7 +257,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { // if all segments are done if (rdata->nbSegments == ulsch_harq->processedSegments) { if (decodeSuccess) { - LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n", + LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for slot %d TBS %d\n", gNB->Mod_id,ulsch_harq->slot,ulsch_harq->TBS); ulsch_harq->status = SCH_IDLE; ulsch_harq->round = 0; @@ -374,7 +384,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, case 245: timing_advance_update /= 32; break; case 273: timing_advance_update /= 32; break; case 66: timing_advance_update /= 12; break; - default: abort(); + case 32: timing_advance_update /= 12; break; + default: AssertFatal(0==1,"No case defined for PRB %d to calculate timing_advance_update\n",gNB->frame_parms.N_RB_DL); } // put timing advance command in 0..63 range @@ -505,7 +516,7 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) uint8_t symbol; unsigned char aa; - for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) { + for(symbol = 0; symbol < (gNB->frame_parms.Ncp==EXTENDED?12:14); symbol++) { // nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0); for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { @@ -519,6 +530,15 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } } + for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { + apply_nr_rotation_ul(&gNB->frame_parms, + gNB->common_vars.rxdataF[aa], + slot_rx, + 0, + gNB->frame_parms.Ncp==EXTENDED?12:14, + gNB->frame_parms.ofdm_symbol_size); + } + } void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { @@ -526,7 +546,9 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1); LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx); - fill_ul_rb_mask(gNB, frame_rx, slot_rx); + if (gNB->frame_parms.frame_type == TDD) + fill_ul_rb_mask(gNB, frame_rx, slot_rx); + gNB_I0_measurements(gNB); for (int i=0;ipucch_pdu; uint16_t num_ucis; - switch (pucch_pdu->format_type) { case 0: - num_ucis = gNB->UL_INFO.uci_ind.num_ucis; gNB->UL_INFO.uci_ind.uci_list = &gNB->uci_pdu_list[0]; gNB->UL_INFO.uci_ind.sfn = frame_rx; @@ -558,8 +578,25 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) gNB->UL_INFO.uci_ind.num_ucis += 1; pucch->active = 0; break; + case 2: + num_ucis = gNB->UL_INFO.uci_ind.num_ucis; + gNB->UL_INFO.uci_ind.uci_list = &gNB->uci_pdu_list[0]; + gNB->UL_INFO.uci_ind.sfn = frame_rx; + gNB->UL_INFO.uci_ind.slot = slot_rx; + gNB->uci_pdu_list[num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE; + gNB->uci_pdu_list[num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_2_3_4_t); + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu_format2 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_2_3_4; + + nr_decode_pucch2(gNB, + slot_rx, + uci_pdu_format2, + pucch_pdu); + + gNB->UL_INFO.uci_ind.num_ucis += 1; + pucch->active = 0; + break; default: - AssertFatal(1==0,"Only PUCCH format 0 is currently supported\n"); + AssertFatal(1==0,"Only PUCCH formats 0 and 2 are currently supported\n"); } } } diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 3b60186fdb..b74494a404 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -103,14 +103,11 @@ void phy_procedures_UE_lte(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type); /*! \brief Scheduling for UE TX procedures in normal subframes. - @param phy_vars_ue Pointer to UE variables on which to act + @param ue Pointer to UE variables on which to act @param proc Pointer to RXn-TXnp4 proc information @param eNB_id Local id of eNB on which to act - @param abstraction_flag Indicator of PHY abstraction - @param mode calib/normal mode - @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying */ -void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, uint8_t thread_id); +void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id); /*! \brief Scheduling for UE RX procedures in normal subframes. @param ue Pointer to UE variables on which to act @@ -306,7 +303,7 @@ int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); @param mu numerology index (0,1,2..) */ void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB); -void nr_process_timing_advance_rar(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance); +void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue, int frame_rx, int nr_slot_rx, uint16_t ta_command); unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb); @@ -388,6 +385,7 @@ void set_tx_harq_id(NR_UE_ULSCH_t *ulsch, int harq_pid, int slot_tx); int get_tx_harq_id(NR_UE_ULSCH_t *ulsch, int slot_tx); int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp); +int is_ssb_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp); /*@}*/ diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 2df917d676..4e6bc7497f 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -52,7 +52,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ int slot = scheduled_response->slot; // Note: we have to handle the thread IDs for this. To be revisited completely. - thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot]; + thread_id = scheduled_response->thread_id; NR_UE_DLSCH_t *dlsch0 = NULL; NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0]; NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0]; @@ -93,7 +93,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ if (dlsch0_harq){ - dlsch0_harq->status = ACTIVE; dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart; dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize; dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs; @@ -154,8 +153,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH; - if (scheduled_response->tx_request){ // TBR todo here it should loop through the number of tx pdus - fapi_nr_tx_request_body_t *tx_req_body = scheduled_response->tx_request->tx_request_body; + if (scheduled_response->tx_request){ + fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[i]; memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length); diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c index 3c3017d658..bf17da9b8c 100644 --- a/openair1/SCHED_NR_UE/harq_nr.c +++ b/openair1/SCHED_NR_UE/harq_nr.c @@ -114,7 +114,7 @@ *********************************************************************/ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted, - NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t nr_tti_rx, uint8_t tx_offset) + NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t slot, uint8_t tx_offset) { if (nr_dci_info_extracted->identifier_dci_formats == DL_DCI) { @@ -124,14 +124,14 @@ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_i dl_harq->harq_ack.vDAI_DL = nr_dci_info_extracted->dai+1; dl_harq->harq_ack.pucch_resource_indicator = nr_dci_info_extracted->pucch_resource_ind; - dl_harq->harq_ack.slot_for_feedback_ack = (nr_tti_rx + nr_dci_info_extracted->pdsch_to_harq_feedback_time_ind)%ue->frame_parms.ttis_per_subframe; + dl_harq->harq_ack.slot_for_feedback_ack = (slot + nr_dci_info_extracted->pdsch_to_harq_feedback_time_ind)%ue->frame_parms.slots_per_subframe; dl_harq->harq_ack.harq_id = nr_dci_info_extracted->harq_process_number; dl_harq->harq_ack.rx_status = downlink_harq_process(dl_harq, dlsch[0]->current_harq_pid, nr_dci_info_extracted->ndi, dlsch[0]->rnti_type); } else if (nr_dci_info_extracted->identifier_dci_formats == UL_DCI) { /* store harq id for which pusch should be transmitted at rx_slot + tx_offset */ - set_tx_harq_id(ulsch, nr_dci_info_extracted->harq_process_number, (nr_tti_rx + tx_offset)%ue->frame_parms.ttis_per_subframe); + set_tx_harq_id(ulsch, nr_dci_info_extracted->harq_process_number, (slot + tx_offset)%ue->frame_parms.slots_per_subframe); ulsch->harq_processes[nr_dci_info_extracted->harq_process_number]->tx_status = uplink_harq_process(ulsch, nr_dci_info_extracted->harq_process_number, nr_dci_info_extracted->ndi, ulsch->rnti_type); } } @@ -491,6 +491,8 @@ harq_result_t downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int dl_harq->round++; + if (dl_harq->harq_ack.ack) dl_harq->status = SCH_IDLE; + result_harq = RETRANSMISSION_HARQ; NR_TST_PHY_PRINTF("[HARQ-DL-PDSCH harqId : %d] reception of a retransmission \n", harq_pid); diff --git a/openair1/SCHED_NR_UE/harq_nr.h b/openair1/SCHED_NR_UE/harq_nr.h index ee6e8625b0..c6d47a91ef 100644 --- a/openair1/SCHED_NR_UE/harq_nr.h +++ b/openair1/SCHED_NR_UE/harq_nr.h @@ -73,12 +73,12 @@ @param nr_dci_info_extracted extracted information from dci @param dlsch downlink context @param ulsch uplink context - @param nr_tti_rx rx slot + @param nr_slot_rx rx slot @param tx_offset slot offset for tx @returns none */ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted, - NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t nr_tti_rx, uint8_t tx_offset); + NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t nr_slot_rx, uint8_t tx_offset); /** \brief This function configures uplink HARQ context @param PHY_VARS_NR_UE ue context diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr.h b/openair1/SCHED_NR_UE/phy_frame_config_nr.h index 3669239578..fcc2fa5838 100644 --- a/openair1/SCHED_NR_UE/phy_frame_config_nr.h +++ b/openair1/SCHED_NR_UE/phy_frame_config_nr.h @@ -61,18 +61,18 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms); /** \brief This function checks nr slot direction : downlink or uplink * @param frame_parms NR DL Frame parameters * @param nr_frame : frame number - * @param nr_tti : slot number + * @param nr_slot : slot number @returns int : downlink or uplink */ -int slot_select_nr(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_tti); +int slot_select_nr(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_slot); /** \brief This function checks nr UE slot direction : downlink or uplink * @param cfg : FAPI Config Request * @param nr_frame : frame number - * @param nr_tti : slot number + * @param nr_slot : slot number @returns int : downlink, uplink or mixed slot type */ -int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti); +int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_slot); /** \brief This function frees tdd configuration for nr * @param frame_parms NR DL Frame parameters diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c index 640ffb4ac3..6254f6a2d2 100644 --- a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c @@ -39,7 +39,7 @@ * *********************************************************************/ -int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) { +int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_slot) { /* for FFD all slot can be considered as an uplink */ int mu = cfg->ssb_config.scs_common, check_slot = 0; @@ -49,7 +49,7 @@ int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) { if (nr_frame%2 == 0) { for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) { + if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) { check_slot++; } } @@ -61,7 +61,7 @@ int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) { check_slot = 0; for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) { + if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) { check_slot++; } } @@ -73,7 +73,7 @@ int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) { } } else { for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<frame_parms.numerology_index; uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL; @@ -170,15 +172,14 @@ void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, // Transmission timing adjustment (TS 38.213 p4.2) ue->timing_advance = bw_scaling / factor_mu; - LOG_D(PHY, "[UE %d] Frame %d Slot %d, Received (RAR) timing advance command %d new value is %u \n", ue->Mod_id, proc->frame_rx, proc->nr_tti_rx, ta_command, ue->timing_advance); + LOG_D(PHY, "[UE %d] Frame %d Slot %d, Received (RAR) timing advance command %d new value is %u \n", ue->Mod_id, frame_rx, nr_slot_rx, ta_command, ue->timing_advance); } void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - uint8_t thread_id){ + uint8_t gNB_id) { //int32_t ulsch_start=0; - int slot_tx = proc->nr_tti_tx; + int slot_tx = proc->nr_slot_tx; int frame_tx = proc->frame_tx; uint8_t harq_pid = 0; runmode_t mode = normal_txrx; @@ -195,8 +196,8 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, if (ue->UE_mode[gNB_id] <= PUSCH || get_softmodem_params()->phy_test == 1){ - if (ue->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->status == ACTIVE) - nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, thread_id, gNB_id); + if (ue->ulsch[proc->thread_id][gNB_id][0]->harq_processes[harq_pid]->status == ACTIVE) + nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, proc->thread_id, gNB_id); if (get_softmodem_params()->usim_test==0) { LOG_D(PHY, "Generating PUCCH\n"); @@ -210,13 +211,13 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, nr_ue_pusch_common_procedures(ue, slot_tx, &ue->frame_parms,1); - //ue->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->pusch_pdu.nrOfLayers); + //ue->ulsch[proc->thread_id][gNB_id][0]->harq_processes[harq_pid]->pusch_pdu.nrOfLayers); } //LOG_M("txdata.m","txs",ue->common_vars.txdata[0],1228800,1,1); /* RACH */ if (get_softmodem_params()->do_ra==1) { - if ((ue->UE_mode[gNB_id] < PUSCH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) { + if ((ue->UE_mode[gNB_id] > NOT_SYNCHED && ue->UE_mode[gNB_id] < PUSCH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) { nr_ue_prach_procedures(ue, proc, gNB_id, mode); } } @@ -239,25 +240,27 @@ void nr_ue_measurement_procedures(uint16_t l, // symbol index of each slot [0 LOG_D(PHY,"ue_measurement_procedures l %u Ncp %d\n",l,ue->frame_parms.Ncp); NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - int nr_tti_rx = proc->nr_tti_rx; + int frame_rx = proc->frame_rx; + int nr_slot_rx = proc->nr_slot_rx; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN); if (l==2) { // UE measurements on symbol 0 - LOG_D(PHY,"Calling measurements nr_tti_rx %d, rxdata %p\n",nr_tti_rx,ue->common_vars.rxdata); + LOG_D(PHY,"Calling measurements nr_slot_rx %d, rxdata %p\n",nr_slot_rx,ue->common_vars.rxdata); /* - nr_ue_measurements(ue, - 0, - 0, - 0, - 0, - nr_tti_rx); -*/ - //(nr_tti_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_ue_measurements(ue, + proc, + 0, + 0, + 0, + 0, + nr_slot_rx); +*/ + //(nr_slot_rx*frame_parms->samples_per_slot+ue->rx_offset) % frame_parms->samples_per_frame #if T_TRACER if(slot == 0) - T(T_UE_PHY_MEAS, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(proc->frame_rx%1024), T_INT(proc->nr_tti_rx), + T(T_UE_PHY_MEAS, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx), T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)), T_INT((int)ue->measurements.rx_rssi_dBm[0]), T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)), @@ -316,7 +319,7 @@ void nr_ue_pbch_procedures(uint8_t gNB_id, DevAssert(ue); int frame_rx = proc->frame_rx; - int nr_tti_rx = proc->nr_tti_rx; + int nr_slot_rx = proc->nr_slot_rx; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN); @@ -343,17 +346,27 @@ void nr_ue_pbch_procedures(uint8_t gNB_id, #ifdef DEBUG_PHY_PROC uint16_t frame_tx; - LOG_D(PHY,"[UE %d] frame %d, nr_tti_rx %d, Received PBCH (MIB): frame_tx %d. N_RB_DL %d\n", + LOG_D(PHY,"[UE %d] frame %d, nr_slot_rx %d, Received PBCH (MIB): frame_tx %d. N_RB_DL %d\n", ue->Mod_id, frame_rx, - nr_tti_rx, + nr_slot_rx, frame_tx, ue->frame_parms.N_RB_DL); #endif } else { - LOG_E(PHY,"[UE %d] frame %d, nr_tti_rx %d, Error decoding PBCH!\n", - ue->Mod_id,frame_rx, nr_tti_rx); + LOG_E(PHY,"[UE %d] frame %d, nr_slot_rx %d, Error decoding PBCH!\n", + ue->Mod_id,frame_rx, nr_slot_rx); + /*FILE *fd; + if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { + fwrite((void *)&ue->common_vars.rxdata[0][0], + sizeof(int32_t), + ue->frame_parms.samples_per_frame, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + }*/ /* write_output("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_subframe,1,1); @@ -385,7 +398,7 @@ void nr_ue_pbch_procedures(uint8_t gNB_id, #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n", - ue->Mod_id,frame_rx, nr_tti_rx, + ue->Mod_id,frame_rx, nr_slot_rx, ue->pbch_vars[gNB_id]->pdu_errors, ue->pbch_vars[gNB_id]->pdu_errors_conseq); #endif @@ -418,7 +431,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, UE_nr_rxtx_proc_t *proc) { int frame_rx = proc->frame_rx; - int nr_tti_rx = proc->nr_tti_rx; + int nr_slot_rx = proc->nr_slot_rx; unsigned int dci_cnt=0; /* @@ -428,10 +441,10 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, #endif int frame_rx = proc->frame_rx; - int nr_tti_rx = proc->nr_tti_rx; + int nr_slot_rx = proc->nr_slot_rx; NR_DCI_ALLOC_t dci_alloc_rx[8]; - //uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1); + //uint8_t next1_thread_id = proc->thread_id== (RX_NB_TH-1) ? 0:(proc->thread_id+1); //uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); @@ -442,8 +455,8 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS]; int nb_searchspace_active=0; - NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]]; - NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]; + NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[proc->thread_id]; + NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[proc->thread_id][gNB_id]; // s in TS 38.212 Subclause 10.1, for each active BWP the UE can deal with 10 different search spaces // Higher layers have updated the number of searchSpaces with are active in the current slot and this value is stored in variable nb_searchspace_total int nb_searchspace_total = pdcch_vars2->nb_search_space; @@ -465,7 +478,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, #ifdef NR_PDCCH_SCHED_DEBUG printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> there is a bug in FAPI to calculate nb_searchspace_total so we set it to 1...\n"); printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> the number of searchSpaces active in the current slot(%d) is %d) \n", - nr_tti_rx,nb_searchspace_total); + nr_slot_rx,nb_searchspace_total); #endif //FK: we define dci_ind and dl_indication as local variables, this way the call to the mac should be thread safe @@ -489,12 +502,12 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, // The following code has been removed as it is handled by higher layers (fapi) // - // Verify that monitoring is required at the slot nr_tti_rx. We will run pdcch procedure only if do_pdcch_monitoring_current_slot=1 + // Verify that monitoring is required at the slot nr_slot_rx. We will run pdcch procedure only if do_pdcch_monitoring_current_slot=1 // For Type0-PDCCH searchspace, we need to calculate the monitoring slot from Tables 13-1 .. 13-15 in TS 38.213 Subsection 13 //NR_UE_SLOT_PERIOD_OFFSET_t sl_period_offset_mon = pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset; //if (sl_period_offset_mon == nr_sl1) { //do_pdcch_monitoring_current_slot=1; // PDCCH monitoring in every slot - //} else if (nr_tti_rx%(uint16_t)sl_period_offset_mon == pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset_offset) { + //} else if (nr_slot_rx%(uint16_t)sl_period_offset_mon == pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset_offset) { //do_pdcch_monitoring_current_slot=1; // PDCCH monitoring in every monitoringSlotPeriodicityAndOffset slot with offset //} @@ -513,7 +526,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, #endif // if (do_pdcch_monitoring_current_slot) { - // the searchSpace indicates that we need to monitor PDCCH in current nr_tti_rx + // the searchSpace indicates that we need to monitor PDCCH in current nr_slot_rx // get the parameters describing the current SEARCHSPACE // the CORESET id applicable to the current SearchSpace //int searchSpace_coreset_id = pdcch_vars2->searchSpace[nb_searchspace_active].controlResourceSetId; @@ -586,8 +599,8 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, searchSpaceType); #endif nr_rx_pdcch(ue, - proc->frame_rx, - nr_tti_rx, + frame_rx, + nr_slot_rx, gNB_id, //(ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI, SISO, @@ -605,9 +618,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, */ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN); - nr_rx_pdcch(ue, - proc->frame_rx, - nr_tti_rx); + nr_rx_pdcch(ue, proc); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT); @@ -620,27 +631,24 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, fapi_nr_dci_indication_t dci_ind={0}; nr_downlink_indication_t dl_indication={0}; - dci_cnt = nr_dci_decoding_procedure(ue, - proc->frame_rx, - nr_tti_rx, - &dci_ind); + dci_cnt = nr_dci_decoding_procedure(ue, proc, &dci_ind); #ifdef NR_PDCCH_SCHED_DEBUG LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT); - //LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_tti_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_tti_rx); + //LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_slot_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_slot_rx); for (int i=0; i rnti %x : format %d\n", - ue->Mod_id,frame_rx%1024,nr_tti_rx,nr_mode_string[ue->UE_mode[gNB_id]], + ue->Mod_id,frame_rx%1024,nr_slot_rx,nr_mode_string[ue->UE_mode[gNB_id]], i + 1, dci_cnt, dci_ind.dci_list[i].rnti, dci_ind.dci_list[i].dci_format); } - ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->dci_received += dci_cnt; + ue->pdcch_vars[proc->thread_id][gNB_id]->dci_received += dci_cnt; dci_ind.number_of_dcis = dci_cnt; /* @@ -662,7 +670,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, &dci_ind.dci_list[i].dci, dci_fields_sizes_cnt[i], dci_alloc_rx[i].format, - nr_tti_rx, + nr_slot_rx, pdcch_vars2->n_RB_BWP[nb_searchspace_active], pdcch_vars2->n_RB_BWP[nb_searchspace_active], crc_scrambled_values); @@ -684,7 +692,8 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, dl_indication.cc_id = ue->CC_id; dl_indication.gNB_index = gNB_id; dl_indication.frame = frame_rx; - dl_indication.slot = nr_tti_rx; + dl_indication.slot = nr_slot_rx; + dl_indication.thread_id = proc->thread_id; dl_indication.rx_ind = NULL; //no data, only dci for now dl_indication.dci_ind = &dci_ind; @@ -702,7 +711,8 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) { - int nr_tti_rx = proc->nr_tti_rx; + int frame_rx = proc->frame_rx; + int nr_slot_rx = proc->nr_slot_rx; int m; int i_mod,eNB_id_i,dual_stream_UE; int first_symbol_flag=0; @@ -721,20 +731,33 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol; uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols; - LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos); + LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos); // do channel estimation for first DMRS only for (m = s0; m < 3; m++) { if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) > 0) { - nr_pdsch_channel_estimation(ue, - 0 /*eNB_id*/, - nr_tti_rx, - 0 /*p*/, - m, - ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12, - pdsch_nb_rb); - LOG_D(PHY,"Channel Estimation in symbol %d\n",m); - break; + for (uint8_t aatx=0; aatx<1; aatx++) {//for MIMO Config: it shall loop over no_layers + nr_pdsch_channel_estimation(ue, + proc, + 0 /*eNB_id*/, + nr_slot_rx, + aatx /*p*/, + m, + ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12, + pdsch_nb_rb); + LOG_D(PHY,"PDSCH Channel estimation gNB id %d, PDSCH antenna port %d, slot %d, symbol %d\n",0,aatx,nr_slot_rx,m); +#if 0 + ///LOG_M: the channel estimation + int nr_frame_rx = proc->frame_rx; + char filename[100]; + for (uint8_t aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", nr_frame_rx, nr_slot_rx, m, aatx,aarx); + int **dl_ch_estimates = ue->pdsch_vars[ue->current_thread_id[nr_slot_rx]][0]->dl_ch_estimates; + LOG_M(filename,"channel_F",&dl_ch_estimates[aatx*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1); + } +#endif + } + break; } } for (m = s0; m < (s1 + s0); m++) { @@ -751,33 +774,35 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ uint8_t slot = 0; if(m >= ue->frame_parms.symbols_per_slot>>1) slot = 1; - start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]); #endif // process DLSCH received in first slot // skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) == 0) { if (nr_rx_pdsch(ue, - pdsch, - eNB_id, - eNB_id_i, - proc->frame_rx, - nr_tti_rx, // nr_tti_rx, - m, - first_symbol_flag, - dual_stream_UE, - i_mod, - dlsch0->current_harq_pid) < 0) - return -1; - } - else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS) - if (pdsch == RA_PDSCH) ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]=ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m-1]; - else if (pdsch == PDSCH) { - if (nr_rx_pdsch(ue, + proc, pdsch, eNB_id, eNB_id_i, - proc->frame_rx, - nr_tti_rx, // nr_tti_rx, + frame_rx, + nr_slot_rx, + m, + first_symbol_flag, + dual_stream_UE, + i_mod, + dlsch0->current_harq_pid) < 0) + return -1; + } + else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS) + if (pdsch == RA_PDSCH) ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]=ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m-1]; + else if (pdsch == PDSCH) { + if (nr_rx_pdsch(ue, + proc, + pdsch, + eNB_id, + eNB_id_i, + frame_rx, + nr_slot_rx, m, first_symbol_flag, dual_stream_UE, @@ -787,13 +812,13 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ } else AssertFatal(1==0,"not RA_PDSCH or PDSCH\n"); } - if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]); + if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]); #if UE_TIMING_TRACE - stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,nr_tti_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",frame_rx,nr_slot_rx,m,ue->dlsch_llr_stats_parallelization[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,nr_tti_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",frame_rx,nr_slot_rx,m,ue->dlsch_llr_stats_parallelization[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif @@ -817,38 +842,38 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ void nr_process_rar(nr_downlink_indication_t *dl_info) { module_id_t module_id = dl_info->module_id; - int cc_id = dl_info->cc_id, frame_rx = dl_info->proc->frame_rx, nr_tti_rx = dl_info->proc->nr_tti_rx, ta_command; + int cc_id = dl_info->cc_id, frame_rx = dl_info->frame, nr_slot_rx = dl_info->slot, ta_command; uint8_t gNB_index = dl_info->gNB_index; // *rar; PHY_VARS_NR_UE *ue = PHY_vars_UE_g[module_id][cc_id]; NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[gNB_index]; UE_MODE_t UE_mode = ue->UE_mode[gNB_index]; NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_index]; - LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Received RAR mode %d\n", module_id, frame_rx, nr_tti_rx, UE_mode); + LOG_D(PHY,"[UE %d][RAPROC] Frame %d slot %d Received RAR mode %d\n", module_id, frame_rx, nr_slot_rx, UE_mode); if (ue->mac_enabled == 1) { if ((UE_mode != PUSCH) && (prach_resources->Msg3 != NULL)) { - LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n", module_id, frame_rx, nr_tti_rx, prach_resources->ra_PreambleIndex); + LOG_D(PHY,"[UE %d][RAPROC] Frame %d slot %d Invoking MAC for RAR (current preamble %d)\n", module_id, frame_rx, nr_slot_rx, prach_resources->ra_PreambleIndex); ta_command = nr_ue_process_rar(ue->Mod_id, cc_id, frame_rx, - nr_tti_rx, + nr_slot_rx, dlsch0->harq_processes[0]->b, - &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti, + &ue->pdcch_vars[dl_info->thread_id][gNB_index]->pdcch_config[0].rnti, prach_resources->ra_PreambleIndex, dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload if (ta_command != 0xffff) { - LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got Temporary C-RNTI %x and timing advance %d from RAR\n", + LOG_D(PHY,"[UE %d][RAPROC] Frame %d slot %d Got Temporary C-RNTI %x and timing advance %d from RAR\n", ue->Mod_id, frame_rx, - nr_tti_rx, - ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti, + nr_slot_rx, + ue->pdcch_vars[dl_info->thread_id][gNB_index]->pdcch_config[0].rnti, ta_command); - nr_process_timing_advance_rar(ue, dl_info->proc, ta_command); + nr_process_timing_advance_rar(ue, frame_rx, nr_slot_rx, ta_command); if (ue->mode != debug_prach) ue->UE_mode[gNB_index] = RA_RESPONSE; @@ -860,7 +885,7 @@ void nr_process_rar(nr_downlink_indication_t *dl_info) { } else { // rar = dlsch0->harq_processes[0]->b+1; // ta_command = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); - // nr_process_timing_advance_rar(ue, dl_info->proc, ta_command); + // nr_process_timing_advance_rar(ue, frame_rx, nr_slot_rx, ta_command); } } @@ -894,9 +919,12 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, int *dlsch_errors, runmode_t mode) { + if (dlsch0==NULL) + AssertFatal(0,"dlsch0 should be defined at this level \n"); + int harq_pid = dlsch0->current_harq_pid; int frame_rx = proc->frame_rx; - int nr_tti_rx = proc->nr_tti_rx; + int nr_slot_rx = proc->nr_slot_rx; int ret=0, ret1=0; NR_UE_PDSCH *pdsch_vars; uint8_t is_cw0_active = 0; @@ -921,9 +949,6 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, uint16_t bw_scaling, start_symbol; float tc_factor; - if (dlsch0==NULL) - AssertFatal(0,"dlsch0 should be defined at this level \n"); - is_cw0_active = dlsch0->harq_processes[harq_pid]->status; nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols; start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol; @@ -938,8 +963,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if(dlsch1) is_cw1_active = dlsch1->harq_processes[harq_pid]->status; - LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, nr_tti_rx, harq_pid, is_cw0_active); - LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, nr_tti_rx, harq_pid, is_cw1_active); + LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw0_active); + LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw1_active); if(is_cw0_active && is_cw1_active) { @@ -956,7 +981,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, case RA_PDSCH: case P_PDSCH: case PDSCH: - pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]; + pdsch_vars = ue->pdsch_vars[proc->thread_id][eNB_id]; break; case PMCH: case PDSCH1: @@ -977,7 +1002,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if (ue->prach_resources[eNB_id]!=NULL) dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI; else { - LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_tti_rx); + LOG_E(PHY,"[UE %d] Frame %d, nr_slot_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_slot_rx); //mac_xface->macphy_exit("prach_resources is NULL"); return; } @@ -1009,18 +1034,18 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, #endif #if 0 - LOG_I(PHY," ------ start ldpc decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, nr_tti_rx, harq_pid); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->Kmimo); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_tti_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols); + LOG_I(PHY," ------ start ldpc decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, nr_slot_rx, harq_pid); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->Kmimo); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols); #endif #if UE_TIMING_TRACE - start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]); + start_meas(&ue->dlsch_decoding_stats[proc->thread_id]); #endif #ifdef UE_DLSCH_PARALLELISATION @@ -1033,20 +1058,22 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, dlsch0->harq_processes[harq_pid], frame_rx, nb_symb_sch, - nr_tti_rx, + nr_slot_rx, harq_pid, pdsch==PDSCH?1:0, dlsch0->harq_processes[harq_pid]->TBS>256?1:0); LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret = %d\n", ret); #else ret = nr_dlsch_decoding(ue, + proc, + eNB_id, pdsch_vars->llr[0], &ue->frame_parms, dlsch0, dlsch0->harq_processes[harq_pid], frame_rx, nb_symb_sch, - nr_tti_rx, + nr_slot_rx, harq_pid, pdsch==PDSCH?1:0, dlsch0->harq_processes[harq_pid]->TBS>256?1:0); @@ -1055,17 +1082,17 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, #endif #if UE_TIMING_TRACE - stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]); + stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]); #if DISABLE_LOG_X printf(" --> Unscrambling for CW0 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); printf("AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n", - frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0)); + frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); #else LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); LOG_I(PHY, "AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n", - frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0)); + frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); #endif #endif @@ -1091,17 +1118,17 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, #endif #if 0 - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->Kmimo); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_tti_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->Kmimo); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols); #endif #if UE_TIMING_TRACE - start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]); + start_meas(&ue->dlsch_decoding_stats[proc->thread_id]); #endif #ifdef UE_DLSCH_PARALLELISATION @@ -1114,20 +1141,22 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, dlsch1->harq_processes[harq_pid], frame_rx, nb_symb_sch, - nr_tti_rx, + nr_slot_rx, harq_pid, pdsch==PDSCH?1:0, dlsch1->harq_processes[harq_pid]->TBS>256?1:0); LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret1 = %d\n", ret1); #else ret1 = nr_dlsch_decoding(ue, + proc, + eNB_id, pdsch_vars->llr[1], &ue->frame_parms, dlsch1, dlsch1->harq_processes[harq_pid], frame_rx, nb_symb_sch, - nr_tti_rx, + nr_slot_rx, harq_pid, pdsch==PDSCH?1:0,//proc->decoder_switch, dlsch1->harq_processes[harq_pid]->TBS>256?1:0); @@ -1136,27 +1165,27 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, #endif #if UE_TIMING_TRACE - stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]); + stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]); #if DISABLE_LOG_X printf(" --> Unscrambling for CW1 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); printf("AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", - frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0)); + frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); #else LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", - frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0)); + frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); #endif #endif LOG_I(PHY,"AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", - frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0)); + frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS); } - LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ \n", frame_rx, nr_tti_rx); + LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ \n", frame_rx, nr_slot_rx); LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS); if(retmax_ldpc_iterations+1){ @@ -1166,9 +1195,10 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, dl_indication.cc_id = ue->CC_id; dl_indication.gNB_index = eNB_id; dl_indication.frame = frame_rx; - dl_indication.slot = nr_tti_rx; + dl_indication.slot = nr_slot_rx; + dl_indication.thread_id = proc->thread_id; dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance - dl_indication.proc=proc; + dl_indication.dci_ind = NULL; //dl_indication.rx_ind->number_pdus switch (pdsch) { @@ -1187,8 +1217,6 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length); rx_ind.number_pdus = 1; - //ue->dl_indication.rx_ind = &dlsch1->harq_processes[harq_pid]->b; //no data, only dci for now - dl_indication.dci_ind = NULL; //&ue->dci_ind; // send to mac if (ue->if_inst && ue->if_inst->dl_indication) ue->if_inst->dl_indication(&dl_indication, ul_time_alignment); @@ -1202,7 +1230,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if(dlsch0->rnti != 0xffff){ LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,subframe_rx, + harq_pid,frame_rx,nr_slot_rx, dlsch0->harq_processes[harq_pid]->rvidx, dlsch0->harq_processes[harq_pid]->round, dlsch0->harq_processes[harq_pid]->mcs, @@ -1212,7 +1240,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if(dlsch0->rnti != 0xffff){ LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,subframe_rx, + harq_pid,frame_rx,nr_slot_rx, dlsch0->harq_processes[harq_pid]->rvidx, dlsch0->harq_processes[harq_pid]->round, dlsch0->harq_processes[harq_pid]->mcs, @@ -1296,15 +1324,15 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, ul_tx_timing_adjustment = 1 + ceil(slots_per_subframe*((N_t_1 + N_t_2 + N_TA_max)*tc_factor + 0.5)/t_subframe); if (ul_time_alignment->apply_ta == 1){ - ul_time_alignment->ta_slot = (nr_tti_rx + ul_tx_timing_adjustment) % slots_per_frame; - if (nr_tti_rx + ul_tx_timing_adjustment > slots_per_frame){ + ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame; + if (nr_slot_rx + ul_tx_timing_adjustment > slots_per_frame){ ul_time_alignment->ta_frame = (frame_rx + 1) % 1024; } else { ul_time_alignment->ta_frame = frame_rx; } // reset TA flag ul_time_alignment->apply_ta = 0; - LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_tti_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot); + LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot); } } @@ -1333,17 +1361,10 @@ void *UE_thread_slot1_dl_processing(void *arg) { UE_nr_rxtx_proc_t *proc = rtd->proc; PHY_VARS_NR_UE *ue = rtd->UE; - int frame_rx; - uint8_t nr_tti_rx; - uint8_t pilot0; uint8_t pilot1; - uint8_t slot1; - - uint8_t next_nr_tti_rx; - uint8_t next_subframe_slot0; proc->instance_cnt_slot1_dl_processing=-1; - proc->nr_tti_rx=proc->sub_frame_start; + proc->nr_slot_rx = proc->sub_frame_start * ue->frame_parms.slots_per_subframe; char threadname[256]; sprintf(threadname,"UE_thread_slot1_dl_processing_%d", proc->sub_frame_start); @@ -1352,9 +1373,9 @@ void *UE_thread_slot1_dl_processing(void *arg) { CPU_ZERO(&cpuset); if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.slot1_proc_one != -1 ) CPU_SET(threads.slot1_proc_one, &cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 ) + if ( RX_NB_TH > 1 && (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 ) CPU_SET(threads.slot1_proc_two, &cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 ) + if ( RX_NB_TH > 2 && (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 ) CPU_SET(threads.slot1_proc_three, &cpuset); init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, @@ -1374,21 +1395,15 @@ void *UE_thread_slot1_dl_processing(void *arg) { exit_fun("nothing to add"); } - /*for(int th_idx=0; th_idx< RX_NB_TH; th_idx++) - { - frame_rx = ue->proc.proc_rxtx[0].frame_rx; - nr_tti_rx = ue->proc.proc_rxtx[0].nr_tti_rx; - printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, nr_tti_rx); - }*/ - frame_rx = proc->frame_rx; - nr_tti_rx = proc->nr_tti_rx; - next_nr_tti_rx = (1+nr_tti_rx)%10; - next_subframe_slot0 = next_nr_tti_rx<<1; + int frame_rx = proc->frame_rx; + uint8_t subframe_rx = proc->nr_slot_rx / ue->frame_parms.slots_per_subframe; + uint8_t next_subframe_rx = (1 + subframe_rx) % NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + uint8_t next_subframe_slot0 = next_subframe_rx * ue->frame_parms.slots_per_subframe; - slot1 = (nr_tti_rx<<1) + 1; - pilot0 = 0; + uint8_t slot1 = proc->nr_slot_rx + 1; + uint8_t pilot0 = 0; - //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, nr_tti_rx); + //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, nr_slot_rx); if (ue->frame_parms.Ncp == 0) { // normal prefix pilot1 = 4; @@ -1398,13 +1413,13 @@ void *UE_thread_slot1_dl_processing(void *arg) { /**** Slot1 FE Processing ****/ #if UE_TIMING_TRACE - start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]); + start_meas(&ue->ue_front_end_per_slot_stat[proc->thread_id][1]); #endif // I- start dl slot1 processing - // do first symbol of next downlink nr_tti_rx for channel estimation + // do first symbol of next downlink nr_slot_rx for channel estimation /* - // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next nr_tti_rx ofdmSym11) - if (nr_subframe_select(&ue->frame_parms,next_nr_tti_rx) != SF_UL) + // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next nr_slot_rx ofdmSym11) + if (nr_subframe_select(&ue->frame_parms,next_nr_slot_rx) != SF_UL) { front_end_fft(ue, pilot0, @@ -1428,7 +1443,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { start_meas(&ue->ofdm_demod_stats); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); - //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot1,l); + //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_slot_rx,slot1,l); front_end_fft(ue, l, slot1, @@ -1441,9 +1456,9 @@ void *UE_thread_slot1_dl_processing(void *arg) { } } // for l=1..l2 - if (nr_subframe_select(&ue->frame_parms,next_nr_tti_rx) != SF_UL) + if (nr_subframe_select(&ue->frame_parms,next_nr_slot_rx) != SF_UL) { - //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_tti_rx,next_subframe_slot0,pilot0); + //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_slot_rx,next_subframe_slot0,pilot0); front_end_fft(ue, pilot0, next_subframe_slot0, @@ -1465,37 +1480,37 @@ void *UE_thread_slot1_dl_processing(void *arg) { } //printf("[slot1 dl processing] ChanEst symbol %d slot %d wait%d\n",l,slot1,wait); } - //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot1,l); + //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_slot_rx,slot1,l); front_end_chanEst(ue, l, slot1, 0); - ue_measurement_procedures(l-1,ue,proc,0,1+(nr_tti_rx<<1),0,ue->mode); + ue_measurement_procedures(l-1,ue,proc,0,slot1,0,ue->mode); } - //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_tti_rx,next_subframe_slot0,pilot0); + //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_slot_rx,next_subframe_slot0,pilot0); front_end_chanEst(ue, pilot0, next_subframe_slot0, 0); - if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1)) + if ( (nr_slot_rx == 0) && (ue->decode_MIB == 1)) { ue_pbch_procedures(0,ue,proc,0); } proc->chan_est_slot1_available = 1; - //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,nr_tti_rx); - //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_tti_rx); + //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,nr_slot_rx); + //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_slot_rx); - //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_tti_rx); + //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_slot_rx); #if UE_TIMING_TRACE - stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]); + stop_meas(&ue->ue_front_end_per_slot_stat[proc->thread_id][1]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_tti_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_slot_rx,ue->ue_front_end_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #else - LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_tti_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_slot_rx,ue->ue_front_end_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #endif #endif @@ -1507,22 +1522,22 @@ void *UE_thread_slot1_dl_processing(void *arg) { usleep(1); wait++; } - //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,nr_tti_rx,wait); + //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,nr_slot_rx,wait); /**** Pdsch Procedure Slot1 ****/ // start slot1 thread for Pdsch Procedure (slot1) // do procedures for C-RNTI - //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,nr_tti_rx); + //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,nr_slot_rx); #if UE_TIMING_TRACE - start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]); + start_meas(&ue->pdsch_procedures_per_slot_stat[proc->thread_id][1]); #endif // start slave thread for Pdsch Procedure (slot1) // do procedures for C-RNTI uint8_t eNB_id = 0; - if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) { + if (ue->dlsch[proc->thread_id][eNB_id][0]->active == 1) { //wait until first ofdm symbol is processed //wait = 0; //while(proc->first_symbol_available == 0) @@ -1530,20 +1545,20 @@ void *UE_thread_slot1_dl_processing(void *arg) { // usleep(1); // wait++; //} - //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,nr_tti_rx,wait); + //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,nr_slot_rx,wait); //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, proc, eNB_id, PDSCH, - ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0], + ue->dlsch[proc->thread_id][eNB_id][0], NULL, (ue->frame_parms.symbols_per_slot>>1), ue->frame_parms.symbols_per_slot-1, abstraction_flag); - LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_slot_rx); + LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_slot_rx); } // do procedures for SI-RNTI @@ -1585,14 +1600,14 @@ void *UE_thread_slot1_dl_processing(void *arg) { } proc->llr_slot1_available=1; - //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,nr_tti_rx); + //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,nr_slot_rx); #if UE_TIMING_TRACE - stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]); + stop_meas(&ue->pdsch_procedures_per_slot_stat[proc->thread_id][1]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_tti_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_slot_rx,ue->pdsch_procedures_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #else - LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_tti_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_slot_rx,ue->pdsch_procedures_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #endif #endif @@ -1612,6 +1627,59 @@ void *UE_thread_slot1_dl_processing(void *arg) { } #endif +int is_ssb_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp) +{ + int mu = fp->numerology_index; + //uint8_t half_frame_index = fp->half_frame_bit; + //uint8_t i_ssb = fp->ssb_index; + uint8_t Lmax = fp->Lmax; + + if (!(frame%(1<<(config->ssb_table.ssb_period-1)))){ + + if(Lmax <= 8) { + if(slot <=3 && (((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*slot)&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*slot +1))&0x80000000) == 0x80000000)) + return 1; + else return 0; + + } + else if(Lmax == 64) { + if (mu == NR_MU_3){ + + if (slot>=0 && slot <= 7){ + if(((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*slot)&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*slot +1))&0x80000000) == 0x80000000) + return 1; + else return 0; + } + else if (slot>=10 && slot <=17){ + if(((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*(slot-2))&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*(slot-2) +1))&0x80000000) == 0x80000000) + return 1; + else return 0; + } + else if (slot>=20 && slot <=27){ + if(((config->ssb_table.ssb_mask_list[1].ssb_mask << 2*(slot-20))&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[1].ssb_mask << (2*(slot-20) +1))&0x80000000) == 0x80000000) + return 1; + else return 0; + } + else if (slot>=30 && slot <=37){ + if(((config->ssb_table.ssb_mask_list[1].ssb_mask << 2*(slot-22))&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[1].ssb_mask << (2*(slot-22) +1))&0x80000000) == 0x80000000) + return 1; + else return 0; + } + else return 0; + + } + + + else if (mu == NR_MU_4) { + AssertFatal(0==1, "not implemented for mu = %d yet\n", mu); + } + else AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu); + } + else AssertFatal(0==1, "Invalid Lmax %u for the synchronization block\n", Lmax); + } + else return 0; + +} int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp) { @@ -1640,21 +1708,24 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, runmode_t mode) { int frame_rx = proc->frame_rx; - int nr_tti_rx = proc->nr_tti_rx; + int nr_slot_rx = proc->nr_slot_rx; int slot_pbch; - NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; + //int slot_ssb; + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0]; fapi_nr_config_request_t *cfg = &ue->nrUE_config; uint8_t nb_symb_pdcch = pdcch_vars->nb_search_space > 0 ? pdcch_vars->pdcch_config[0].coreset.duration : 0; uint8_t dci_cnt = 0; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; + //NR_UE_MAC_INST_t *mac = get_mac_inst(0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); - LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx); + LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_slot_rx); /* - uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1); + uint8_t next1_thread_id = proc->thread_id== (RX_NB_TH-1) ? 0:(proc->thread_id+1); uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); */ @@ -1664,47 +1735,61 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if (pdcch_vars->nb_search_space > 0) get_coreset_rballoc(pdcch_vars->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb); - slot_pbch = is_pbch_in_slot(cfg, frame_rx, nr_tti_rx, fp); + slot_pbch = is_pbch_in_slot(cfg, frame_rx, nr_slot_rx, fp); + //slot_ssb = is_ssb_in_slot(cfg, frame_rx, nr_slot_rx, fp); // looking for pbch only in slot where it is supposed to be if ((ue->decode_MIB == 1) && slot_pbch) { - LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); for (int i=1; i<4; i++) { - nr_slot_fep(ue, - (ue->symbol_offset+i)%(fp->symbols_per_slot), - nr_tti_rx, - 0, - 0); + nr_slot_fep(ue, + proc, + (ue->symbol_offset+i)%(fp->symbols_per_slot), + nr_slot_rx, + 0, + 0); #if UE_TIMING_TRACE - start_meas(&ue->dlsch_channel_estimation_stats); + start_meas(&ue->dlsch_channel_estimation_stats); #endif - nr_pbch_channel_estimation(ue,0,nr_tti_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit); + nr_pbch_channel_estimation(ue,proc,0,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit); #if UE_TIMING_TRACE - stop_meas(&ue->dlsch_channel_estimation_stats); + stop_meas(&ue->dlsch_channel_estimation_stats); #endif - + } + + //if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){ + nr_ue_rsrp_measurements(ue, proc, nr_slot_rx, 0); + //} + + nr_ue_pbch_procedures(gNB_id, ue, proc, 0); if (ue->no_timing_correction==0) { - LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction); + LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); nr_adjust_synch_ue(fp, ue, gNB_id, frame_rx, - nr_tti_rx, + nr_slot_rx, 0, 16384); } } + if ((frame_rx%64 == 0) && (nr_slot_rx==0)) { + printf("============================================\n"); + LOG_I(PHY,"Harq round stats for Downlink: %d/%d/%d/%d DLSCH errors: %d\n",ue->dl_stats[0],ue->dl_stats[1],ue->dl_stats[2],ue->dl_stats[3],ue->dl_stats[4]); + printf("============================================\n"); + } + #ifdef NR_PDCCH_SCHED nr_gold_pdcch(ue, 0, 2); - LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); for (uint16_t l=0; lfirst_carrier_offset,pdcch_vars->pdcch_config[0].BWPStart,coreset_start_rb); if (coreset_nb_rb > 0) nr_pdcch_channel_estimation(ue, - 0, - nr_tti_rx, - l, - fp->first_carrier_offset+(pdcch_vars->pdcch_config[0].BWPStart + coreset_start_rb)*12, - coreset_nb_rb); - + proc, + 0, + nr_slot_rx, + l, + fp->first_carrier_offset+(pdcch_vars->pdcch_config[0].BWPStart + coreset_start_rb)*12, + coreset_nb_rb); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE stop_meas(&ue->ofdm_demod_stats); #endif //printf("phy procedure pdcch start measurement l =%d\n",l); - //nr_ue_measurement_procedures(l,ue,proc,gNB_id,(nr_tti_rx),mode); + //nr_ue_measurement_procedures(l,ue,proc,gNB_id,(nr_slot_rx),mode); } @@ -1742,11 +1829,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if (dci_cnt > 0) { - LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_tti_rx, dci_cnt); + LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt); NR_UE_DLSCH_t *dlsch = NULL; - if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->active == 1){ - dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]; + if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1){ + dlsch = ue->dlsch[proc->thread_id][gNB_id][0]; } else if (ue->dlsch_ra[0]->active == 1){ dlsch = ue->dlsch_ra[0]; } @@ -1758,7 +1845,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, uint16_t start_symb_sch = dlsch0_harq->start_symbol; int symb_dmrs = -1; - LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); //to update from pdsch config for (int i=0;i<4;i++) if (((1<dlDmrsSymbPos) > 0) {symb_dmrs=i;break;} @@ -1768,14 +1855,15 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ nr_slot_fep(ue, - m, //to be updated from higher layer - nr_tti_rx, - 0, - 0); + proc, + m, //to be updated from higher layer + nr_slot_rx, + 0, + 0); } } } else { - LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_tti_rx); + LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_slot_rx); } #endif //NR_PDCCH_SCHED @@ -1785,25 +1873,25 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, #endif // do procedures for C-RNTI int ret_pdsch = 0; - if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->active == 1) { + if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) { //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); ret_pdsch = nr_ue_pdsch_procedures(ue, proc, gNB_id, PDSCH, - ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0], + ue->dlsch[proc->thread_id][gNB_id][0], NULL); //printf("phy procedure pdsch start measurement\n"); - nr_ue_measurement_procedures(2,ue,proc,gNB_id,nr_tti_rx,mode); + nr_ue_measurement_procedures(2,ue,proc,gNB_id,nr_slot_rx,mode); /* - write_output("rxF.m","rxF",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],fp->ofdm_symbol_size*14,1,1); - write_output("rxF_ch.m","rxFch",&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->dl_ch_estimates[0][0],fp->ofdm_symbol_size*14,1,1); - write_output("rxF_ch_ext.m","rxFche",&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->dl_ch_estimates_ext[0][2*50*12],50*12,1,1); - write_output("rxF_ext.m","rxFe",&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->rxdataF_ext[0][0],50*12*14,1,1); - write_output("rxF_comp.m","rxFc",&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->rxdataF_comp0[0][0],fp->N_RB_DL*12*14,1,1); - write_output("rxF_llr.m","rxFllr",ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->llr[0],(nb_symb_sch-1)*50*12+50*6,1,0); + write_output("rxF.m","rxF",&ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0],fp->ofdm_symbol_size*14,1,1); + write_output("rxF_ch.m","rxFch",&ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates[0][0],fp->ofdm_symbol_size*14,1,1); + write_output("rxF_ch_ext.m","rxFche",&ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[0][2*50*12],50*12,1,1); + write_output("rxF_ext.m","rxFe",&ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_ext[0][0],50*12*14,1,1); + write_output("rxF_comp.m","rxFc",&ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_comp0[0][0],fp->N_RB_DL*12*14,1,1); + write_output("rxF_llr.m","rxFllr",ue->pdsch_vars[proc->thread_id][gNB_id]->llr[0],(nb_symb_sch-1)*50*12+50*6,1,0); */ //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); @@ -1813,24 +1901,48 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if ((ue->dlsch_SI[gNB_id]) && (ue->dlsch_SI[gNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - SI_PDSCH, - ue->dlsch_SI[gNB_id], - NULL); + proc, + gNB_id, + SI_PDSCH, + ue->dlsch_SI[gNB_id], + NULL); + nr_ue_dlsch_procedures(ue, + proc, + gNB_id, + SI_PDSCH, + ue->dlsch_SI[gNB_id], + NULL, + &ue->dlsch_SI_errors[gNB_id], + mode); + + // deactivate dlsch once dlsch proc is done + ue->dlsch_SI[gNB_id]->active = 0; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT); } - // do procedures for SI-RNTI + // do procedures for P-RNTI if ((ue->dlsch_p[gNB_id]) && (ue->dlsch_p[gNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN); nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - P_PDSCH, - ue->dlsch_p[gNB_id], - NULL); + proc, + gNB_id, + P_PDSCH, + ue->dlsch_p[gNB_id], + NULL); + + nr_ue_dlsch_procedures(ue, + proc, + gNB_id, + P_PDSCH, + ue->dlsch_p[gNB_id], + NULL, + &ue->dlsch_p_errors[gNB_id], + mode); + + // deactivate dlsch once dlsch proc is done + ue->dlsch_p[gNB_id]->active = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT); } @@ -1839,15 +1951,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN); nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - RA_PDSCH, - ue->dlsch_ra[gNB_id], - NULL); - - // #if UE_TIMING_TRACE - // start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); - // #endif + proc, + gNB_id, + RA_PDSCH, + ue->dlsch_ra[gNB_id], + NULL); nr_ue_dlsch_procedures(ue, proc, @@ -1858,28 +1966,20 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, &ue->dlsch_ra_errors[gNB_id], mode); - // #if UE_TIMING_TRACE - // stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); - #if DISABLE_LOG_X - printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); - printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0)); - #else - LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0)); - LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0)); - #endif - // #endif + // deactivate dlsch once dlsch proc is done + ue->dlsch_ra[gNB_id]->active = 0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } // do procedures for C-RNTI - if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->active == 1) { + if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) { - LOG_D(PHY, "DLSCH data reception at nr_tti_rx: %d \n \n", nr_tti_rx); + LOG_D(PHY, "DLSCH data reception at nr_slot_rx: %d \n \n", nr_slot_rx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); #if UE_TIMING_TRACE - start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); + start_meas(&ue->dlsch_procedures_stat[proc->thread_id]); #endif if (ret_pdsch >= 0) @@ -1887,26 +1987,26 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, proc, gNB_id, PDSCH, - ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0], - ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][1], + ue->dlsch[proc->thread_id][gNB_id][0], + ue->dlsch[proc->thread_id][gNB_id][1], &ue->dlsch_errors[gNB_id], mode); #if UE_TIMING_TRACE - stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); + stop_meas(&ue->dlsch_procedures_stat[proc->thread_id]); #if DISABLE_LOG_X - printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",nr_tti_rx,ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); - printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_tti_rx,ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); + printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",nr_slot_rx,ue->pdsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); + printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); #else - LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",nr_tti_rx,ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); - LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_tti_rx,ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",nr_slot_rx,ue->pdsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); #endif #endif // deactivate dlsch once dlsch proc is done - ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->active = 0; + ue->dlsch[proc->thread_id][gNB_id][0]->active = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); @@ -1917,98 +2017,35 @@ start_meas(&ue->generic_stat); #if 0 - if(nr_tti_rx==5 && ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->current_harq_pid]->nb_rb > 20){ + if(nr_slot_rx==5 && ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid]->nb_rb > 20){ //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); //write_output("llr.m","llr", &ue->pdsch_vars[gNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); - write_output("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1); + write_output("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1); //write_output("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1); //write_output("rxdataF0_previous.m" , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1); - write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[0][0][0],14*fp->ofdm_symbol_size,1,1); - write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_estimates_ext[0][0],14*fp->N_RB_DL*12,1,1); - write_output("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->rxdataF_comp0[0][0],14*fp->N_RB_DL*12,1,1); - //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_mag0[0][0],14*fp->N_RB_DL*12,1,1); - //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_magb0[0][0],14*fp->N_RB_DL*12,1,1); + write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].dl_ch_estimates[0][0][0],14*fp->ofdm_symbol_size,1,1); + write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[proc->thread_id][0]->dl_ch_estimates_ext[0][0],14*fp->N_RB_DL*12,1,1); + write_output("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[proc->thread_id][0]->rxdataF_comp0[0][0],14*fp->N_RB_DL*12,1,1); + //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[proc->thread_id][0]->dl_ch_mag0[0][0],14*fp->N_RB_DL*12,1,1); + //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[proc->thread_id][0]->dl_ch_magb0[0][0],14*fp->N_RB_DL*12,1,1); AssertFatal (0,""); } #endif - // do procedures for SI-RNTI - if ((ue->dlsch_SI[gNB_id]) && (ue->dlsch_SI[gNB_id]->active == 1)) { - nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - SI_PDSCH, - ue->dlsch_SI[gNB_id], - NULL); - - /*ue_dlsch_procedures(ue, - proc, - gNB_id, - SI_PDSCH, - ue->dlsch_SI[gNB_id], - NULL, - &ue->dlsch_SI_errors[gNB_id], - mode, - abstraction_flag); - ue->dlsch_SI[gNB_id]->active = 0;*/ - } - - // do procedures for P-RNTI - if ((ue->dlsch_p[gNB_id]) && (ue->dlsch_p[gNB_id]->active == 1)) { - nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - P_PDSCH, - ue->dlsch_p[gNB_id], - NULL); - - - /*ue_dlsch_procedures(ue, - proc, - gNB_id, - P_PDSCH, - ue->dlsch_p[gNB_id], - NULL, - &ue->dlsch_p_errors[gNB_id], - mode, - abstraction_flag);*/ - ue->dlsch_p[gNB_id]->active = 0; - } - // do procedures for RA-RNTI - if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1)) { - nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - RA_PDSCH, - ue->dlsch_ra[gNB_id], - NULL); - - /*ue_dlsch_procedures(ue, - proc, - gNB_id, - RA_PDSCH, - ue->dlsch_ra[gNB_id], - NULL, - &ue->dlsch_ra_errors[gNB_id], - mode, - abstraction_flag);*/ - ue->dlsch_ra[gNB_id]->active = 0; - } - // duplicate harq structure - /* - uint8_t current_harq_pid = ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->current_harq_pid; - NR_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->harq_processes[current_harq_pid]; +/* + uint8_t current_harq_pid = ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid; + NR_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[current_harq_pid]; NR_DL_UE_HARQ_t *harq_processes_dest = ue->dlsch[next1_thread_id][gNB_id][0]->harq_processes[current_harq_pid]; NR_DL_UE_HARQ_t *harq_processes_dest1 = ue->dlsch[next2_thread_id][gNB_id][0]->harq_processes[current_harq_pid]; */ - /*nr_harq_status_t *current_harq_ack = &ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->harq_ack[nr_tti_rx]; - nr_harq_status_t *harq_ack_dest = &ue->dlsch[next1_thread_id][gNB_id][0]->harq_ack[nr_tti_rx]; - nr_harq_status_t *harq_ack_dest1 = &ue->dlsch[next2_thread_id][gNB_id][0]->harq_ack[nr_tti_rx]; + /*nr_harq_status_t *current_harq_ack = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_ack[nr_slot_rx]; + nr_harq_status_t *harq_ack_dest = &ue->dlsch[next1_thread_id][gNB_id][0]->harq_ack[nr_slot_rx]; + nr_harq_status_t *harq_ack_dest1 = &ue->dlsch[next2_thread_id][gNB_id][0]->harq_ack[nr_slot_rx]; */ //copy_harq_proc_struct(harq_processes_dest, current_harq_processes); @@ -2017,7 +2054,7 @@ start_meas(&ue->generic_stat); //copy_harq_proc_struct(harq_processes_dest1, current_harq_processes); //copy_ack_struct(harq_ack_dest1, current_harq_ack); -if (nr_tti_rx==9) { +if (nr_slot_rx==9) { if (frame_rx % 10 == 0) { if ((ue->dlsch_received[gNB_id] - ue->dlsch_received_last[gNB_id]) != 0) ue->dlsch_fer[gNB_id] = (100*(ue->dlsch_errors[gNB_id] - ue->dlsch_errors_last[gNB_id]))/(ue->dlsch_received[gNB_id] - ue->dlsch_received_last[gNB_id]); @@ -2054,17 +2091,17 @@ phy_procedures_emos_UE_RX(ue,slot,gNB_id); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE -stop_meas(&ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]]); +stop_meas(&ue->phy_proc_rx[proc->thread_id]); #if DISABLE_LOG_X -printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_tti_rx,ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); +printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_slot_rx,ue->phy_proc_rx[proc->thread_id].p_time/(cpuf*1000.0)); #else -LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_tti_rx,ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); +LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_slot_rx,ue->phy_proc_rx[proc->thread_id].p_time/(cpuf*1000.0)); #endif #endif //#endif //pdsch -LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_tti_rx); +LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_slot_rx); return (0); } @@ -2073,7 +2110,7 @@ uint8_t nr_is_cqi_TXOp(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { - int subframe = proc->subframe_tx; + int subframe = proc->nr_slot_tx / ue->frame_parms.slots_per_subframe; int frame = proc->frame_tx; CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[gNB_id].CQI_ReportPeriodic; @@ -2095,7 +2132,7 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { - int subframe = proc->subframe_tx; + int subframe = proc->nr_slot_tx / ue->frame_parms.slots_per_subframe; int frame = proc->frame_tx; CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[gNB_id].CQI_ReportPeriodic; int log2Mri = cqirep->ri_ConfigIndex/161; @@ -2119,7 +2156,7 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue, // - power control as per 38.213 ch 7.4 void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t runmode) { - int frame_tx = proc->frame_tx, nr_tti_tx = proc->nr_tti_tx, prach_power; // tx_amp + int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp uint16_t /*preamble_tx = 50,*/ pathloss; uint8_t mod_id = ue->Mod_id; UE_MODE_t UE_mode = get_nrUE_mode(mod_id, ue->CC_id, gNB_id); @@ -2128,6 +2165,11 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); + if (!prach_resources->init_msg1 && (frame_tx == (ue->prach_resources[gNB_id]->sync_frame + 150) % MAX_FRAME_NUMBER)){ + ue->prach_cnt = 0; + prach_resources->init_msg1 = 1; + } + if (ue->mac_enabled == 0){ // prach_resources->ra_PreambleIndex = preamble_tx; prach_resources->ra_TDD_map_index = 0; @@ -2137,46 +2179,41 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t } else { // ask L2 for RACH transport if ((runmode != rx_calib_ue) && (runmode != rx_calib_ue_med) && (runmode != rx_calib_ue_byp) && (runmode != no_L2_connect) ) { - LOG_D(PHY, "Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_tti_tx); + LOG_D(PHY, "Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_slot_tx); // flush Msg3 Buffer if (prach_resources->Msg3 == NULL){ for(int i = 0; iulsch_Msg3_active[i] = 0; } } - nr_prach = nr_ue_get_rach(ue->prach_resources[gNB_id], mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_tti_tx); + nr_prach = nr_ue_get_rach(ue->prach_resources[gNB_id], &ue->prach_vars[0]->prach_pdu, mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_slot_tx); } } - if (!prach_resources->init_msg1 && (frame_tx > ue->prach_resources[gNB_id]->sync_frame + 150)){ - ue->prach_cnt = 0; - prach_resources->init_msg1 = 1; - } - if (ue->prach_resources[gNB_id] != NULL && nr_prach == 1 && prach_resources->init_msg1) { pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id); LOG_D(PHY,"runmode %d\n",runmode); if ((ue->mac_enabled == 1) && (runmode != calib_prach_tx)) { - ue->tx_power_dBm[nr_tti_tx] = prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss; + ue->tx_power_dBm[nr_slot_tx] = prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss; } - LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d : Generating PRACH, preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x\n", + LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_slot_tx %d : Generating PRACH, preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x\n", ue->Mod_id, frame_tx, - nr_tti_tx, + nr_slot_tx, prach_resources->ra_PreambleIndex, pathloss, - ue->tx_power_dBm[nr_tti_tx], + ue->tx_power_dBm[nr_slot_tx], prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER, prach_resources->ra_RNTI); - //ue->tx_total_RE[nr_tti_tx] = 96; // todo + //ue->tx_total_RE[nr_slot_tx] = 96; // todo ue->prach_vars[gNB_id]->amp = AMP; /* #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - tx_amp = get_tx_amp_prach(ue->tx_power_dBm[nr_tti_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL); + tx_amp = get_tx_amp_prach(ue->tx_power_dBm[nr_slot_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL); if (tx_amp != -1) ue->prach_vars[gNB_id]->amp = tx_amp; #else @@ -2184,38 +2221,38 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t #endif */ if ((runmode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) - LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d : PRACH TX power %d dBm, amp %d\n", ue->Mod_id, + LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_slot_tx %d : PRACH TX power %d dBm, amp %d\n", ue->Mod_id, proc->frame_rx, - proc->nr_tti_tx, - ue->tx_power_dBm[nr_tti_tx], + proc->nr_slot_tx, + ue->tx_power_dBm[nr_slot_tx], ue->prach_vars[gNB_id]->amp); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN); - prach_power = generate_nr_prach(ue, gNB_id, nr_tti_tx); + prach_power = generate_nr_prach(ue, gNB_id, nr_slot_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT); LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", ue->Mod_id, pathloss, - ue->tx_power_dBm[nr_tti_tx], + ue->tx_power_dBm[nr_slot_tx], dB_fixed(prach_power), ue->prach_vars[gNB_id]->amp); if (ue->mac_enabled == 1) nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id); - LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d: Generated PRACH Msg1 (gNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB) \n", + LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_slot_tx %d: Generated PRACH Msg1 (gNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB) \n", ue->Mod_id, frame_tx, - nr_tti_tx, + nr_slot_tx, gNB_id, prach_resources->ra_PreambleIndex, - ue->tx_power_dBm[nr_tti_tx], + ue->tx_power_dBm[nr_slot_tx], pathloss); - LOG_D(PHY,"[UE %d] frame %d nr_tti_tx %d : prach_cnt %d\n", ue->Mod_id, frame_tx, nr_tti_tx, ue->prach_cnt); + LOG_D(PHY,"[UE %d] frame %d nr_slot_tx %d : prach_cnt %d\n", ue->Mod_id, frame_tx, nr_slot_tx, ue->prach_cnt); ue->prach_cnt++; diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c index b51c8afbb0..e2e2143287 100644 --- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c @@ -97,7 +97,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, G_b_f_c = 0; } else { - G_b_f_c = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][gNB_id][0]->g_pucch; + G_b_f_c = ue->dlsch[proc->thread_id][gNB_id][0]->g_pucch; LOG_W(PHY,"PUCCH Transmit power control command not yet implemented for NR : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__); return (PUCCH_POWER_DEFAULT); } @@ -169,7 +169,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, //int K_PUCCH = 0; if (O_ACK != 0) { /* it assumes that PDCCH is in the first symbol of receive slot FFS TDDO NR */ - //int slots_gap = (proc->nr_tti_tx > proc->nr_tti_rx ? (proc->nr_tti_tx - proc->nr_tti_rx - 1) : ((proc->nr_tti_tx + ue->frame_parms.ttis_per_subframe) - proc->nr_tti_rx - 1)); + //int slots_gap = (proc->nr_slot_tx > proc->nr_slot_rx ? (proc->nr_slot_tx - proc->nr_slot_rx - 1) : ((proc->nr_slot_tx + ue->frame_parms.slots_per_subframe) - proc->nr_slot_rx - 1)); //K_PUCCH = (slots_gap * (ue->frame_parms.symbols_per_tti)) - 1; } else { diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 5a76887368..9a19aef985 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -37,6 +37,8 @@ #include "PHY/defs_nr_UE.h" #include #include +#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" +#include "openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h" #ifndef NO_RAT_NR @@ -54,12 +56,50 @@ uint8_t nr_is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id); uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id); + +long +binary_search_float_nr( + float elements[], + long numElem, + float value +) +//----------------------------------------------------------------------------- +{ + long first, last, middle; + first = 0; + last = numElem-1; + middle = (first+last)/2; + + if(value < elements[0]) { + return first; + } + + if(value >= elements[last]) { + return last; + } + + while (last - first > 1) { + if (elements[middle] > value) { + last = middle; + } else { + first = middle; + } + + middle = (first+last)/2; + } + + if (first < 0 || first >= numElem) { + LOG_E(RRC,"\n Error in binary search float!"); + } + + return first; +} /* void nr_generate_pucch0(int32_t **txdataF, NR_DL_FRAME_PARMS *frame_parms, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t mcs, uint8_t nrofSymbols, uint8_t startingSymbolIndex, @@ -70,7 +110,7 @@ void nr_generate_pucch1(int32_t **txdataF, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint16_t startingPRB, @@ -83,7 +123,7 @@ void nr_generate_pucch2(int32_t **txdataF, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint8_t nrofPRB, @@ -96,7 +136,7 @@ void nr_generate_pucch3_4(int32_t **txdataF, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint8_t nrofPRB, @@ -170,7 +210,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ uint64_t pucch_payload = 0; uint32_t csi_payload = 0; int frame_tx = proc->frame_tx; - int nr_tti_tx = proc->nr_tti_tx; + int nr_slot_tx = proc->nr_slot_tx; int Mod_id = ue->Mod_id; int CC_id = ue->CC_id; @@ -198,18 +238,18 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ /* update current context */ - int subframe_number = (proc->nr_tti_rx)/(ue->frame_parms.slots_per_subframe);//ttis_per_subframe); + int subframe_number = proc->nr_slot_rx / ue->frame_parms.slots_per_subframe; nb_pucch_format_4_in_subframes[subframe_number] = 0; /* reset pucch format 4 counter at current rx position */ - int dl_harq_pid = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid; + int dl_harq_pid = ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid; - if (dl_harq_pid < ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->number_harq_processes_for_pdsch) { + if (dl_harq_pid < ue->dlsch[proc->thread_id][gNB_id][0]->number_harq_processes_for_pdsch) { /* pucch indicator can be reseted in function get_downlink_ack so it should be get now */ - pucch_resource_indicator = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack.pucch_resource_indicator; + pucch_resource_indicator = ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack.pucch_resource_indicator; } /* Part - I - * Collect feedback that should be transmitted at this nr_tti_tx : + * Collect feedback that should be transmitted at this nr_slot_tx : * - ACK/NACK, SR, CSI (CQI, RI, ...) */ @@ -221,11 +261,11 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ /* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */ sr_payload = nr_ue_get_SR(Mod_id, - CC_id, - frame_tx, - gNB_id, - 0,//ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti, - nr_tti_tx); // nr_tti_rx used for meas gap + CC_id, + frame_tx, + gNB_id, + 0,//ue->pdcch_vars[proc->thread_id][gNB_id]->crnti, + nr_slot_tx); // nr_slot_rx used for meas gap } else { sr_payload = 1; @@ -241,7 +281,17 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ ri_status = ((ue->cqi_report_config[gNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) && (nr_is_ri_TXOp(ue,proc,gNB_id) == 1)); - csi_status = get_csi_nr(ue, gNB_id, &csi_payload); + + NR_CSI_MeasConfig_t *csi_MeasConfig = mac->scg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + + uint16_t report_slot_csi =csi_MeasConfig->csi_ReportConfigToAddModList->list.array[0]->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320; + + //if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){ + if (report_slot_csi == proc->nr_slot_tx) + csi_status = get_csi_nr(mac, ue, gNB_id, &csi_payload); + else + csi_status = 0; + //} O_CSI = cqi_status + ri_status + csi_status; @@ -251,8 +301,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ if(O_ACK == 0) { N_UCI = O_SR + O_CSI; if ((N_UCI == 0) || ((O_CSI == 0) && (sr_payload == 0))) { /* TS 38.213 9.2.4 UE procedure for reporting SR */ - NR_TST_PHY_PRINTF("PUCCH No feedback AbsSubframe %d.%d \n", frame_tx%1024, nr_tti_tx); - LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d \n", frame_tx%1024, nr_tti_tx); + NR_TST_PHY_PRINTF("PUCCH No feedback AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx); + LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx); return (FALSE); } else { @@ -304,7 +354,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ int occ_length = 0; int occ_Index = 0; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack; if (select_pucch_resource(ue, mac, gNB_id, N_UCI, pucch_resource_indicator, &initial_pucch_id, &pucch_resource_set, &pucch_resource_id, harq_status) == TRUE) { @@ -339,7 +389,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ if ((ue->UE_mode[gNB_id] != PUSCH) && (O_ACK > 1)) { O_ACK = 1; pucch_ack_payload &= 0x1; /* take only first ack */ - LOG_W(PHY,"PUCCH ue is not expected to generate more than one HARQ-ACK at AbsSubframe %d.%d \n", frame_tx%1024, nr_tti_tx); + LOG_W(PHY,"PUCCH ue is not expected to generate more than one HARQ-ACK at AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx); } NR_TST_PHY_PRINTF("PUCCH common configuration with index %d \n", initial_pucch_id); } @@ -392,12 +442,12 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ } } else { - LOG_W(PHY,"PUCCH No PUCCH resource found at AbsSubframe %d.%d \n", frame_tx%1024, nr_tti_tx); + LOG_W(PHY,"PUCCH No PUCCH resource found at AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx); return (FALSE); } int max_code_rate = 0; - int Q_m = BITS_PER_SYMBOL_QPSK; /* default pucch modulation type is QPSK with 2 bits per symbol */ + //int Q_m = BITS_PER_SYMBOL_QPSK; /* default pucch modulation type is QPSK with 2 bits per symbol */ int N_sc_ctrl_RB = 0; int O_CRC = 0; @@ -426,21 +476,21 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ case pucch_format3_nr: { nb_of_prbs = pucch_resource->format.choice.format3->nrofPRBs; - if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3->choice.setup->pi2BPSK[0] == 1) { - Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */ - } + //if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3->choice.setup->pi2BPSK[0] == 1) { + // Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */ + //} N_sc_ctrl_RB = N_SC_RB; nb_symbols = nb_symbols_excluding_dmrs[nb_symbols_total-4][index_additional_dmrs][index_hopping]; break; } case pucch_format4_nr: { - if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4->choice.setup->pi2BPSK[0] == 1) { - Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */ - } + //if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4->choice.setup->pi2BPSK[0] == 1) { + // Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */ + //} nb_symbols = nb_symbols_excluding_dmrs[nb_symbols_total-4][index_additional_dmrs][index_hopping]; nb_of_prbs = 1; - subframe_number = nr_tti_tx/(ue->frame_parms.slots_per_subframe);//ttis_per_subframe); + subframe_number = nr_slot_tx / ue->frame_parms.slots_per_subframe; nb_pucch_format_4_in_subframes[subframe_number]++; /* increment number of transmit pucch 4 in current subframe */ NR_TST_PHY_PRINTF("PUCCH Number of pucch format 4 in subframe %d is %d \n", subframe_number, nb_pucch_format_4_in_subframes[subframe_number]); N_sc_ctrl_RB = N_SC_RB/(nb_pucch_format_4_in_subframes[subframe_number]); @@ -464,26 +514,27 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ /* TS 38.212 6.3.1.2 Code block segmentation and CRC attachment */ /* crc attachment can be done depending of payload size */ - if (N_UCI < 11) { - O_CRC = 0; /* no additional crc bits */ - } - else if ((N_UCI >= 12) && (N_UCI <= 19)) { - O_CRC = 6; /* number of additional crc bits */ - } - else if (N_UCI >= 20) { - O_CRC = 11; /* number of additional crc bits */ - } +// if (N_UCI < 11) { +// O_CRC = 0; /* no additional crc bits */ +// } +// else if ((N_UCI >= 12) && (N_UCI <= 19)) { +// O_CRC = 6; /* number of additional crc bits */ +// } +// else if (N_UCI >= 20) { +// O_CRC = 11; /* number of additional crc bits */ +// } N_UCI = N_UCI + O_CRC; /* for format 2 and 3, number of prb should be adjusted to minimum value which cope to information size */ - if (nb_of_prbs > 1 ) { + /*if (nb_of_prbs > 1 ) { int nb_prb_min = 0; int payload_in_bits; do { nb_prb_min++; - payload_in_bits = (nb_prb_min * N_sc_ctrl_RB * nb_symbols * Q_m * max_code_rate)/100; /* code rate has been multiplied by 100 */ - NR_TST_PHY_PRINTF("PUCCH Adjust number of prb : (N_UCI : %d ) (payload_in_bits : %d) (N_sc_ctrl_RB : %d) (nb_symbols : %d) (Q_m : %d) (max_code_rate*100 : %d) \n", + payload_in_bits = (nb_prb_min * N_sc_ctrl_RB * nb_symbols * Q_m * max_code_rate)/100; */ /* code rate has been multiplied by 100 */ + + /*NR_TST_PHY_PRINTF("PUCCH Adjust number of prb : (N_UCI : %d ) (payload_in_bits : %d) (N_sc_ctrl_RB : %d) (nb_symbols : %d) (Q_m : %d) (max_code_rate*100 : %d) \n", N_UCI, payload_in_bits, N_sc_ctrl_RB, nb_symbols, Q_m, max_code_rate); } while (N_UCI > payload_in_bits); @@ -494,7 +545,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ else { nb_of_prbs = nb_prb_min; } - } + }*/ /* TS 38.213 9.2.4 for a positive SR transmission, payload b(0) = 0 */ if ((O_SR == 1) && (format == pucch_format1_nr)) { @@ -544,7 +595,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ pucch_payload = pucch_payload | (csi_payload << (O_ACK + O_SR)) | (sr_payload << O_ACK) | pucch_ack_payload; NR_TST_PHY_PRINTF("PUCCH ( AbsSubframe : %d.%d ) ( total payload size %d data 0x%02x ) ( ack length %d data 0x%02x ) ( sr length %d value %d ) ( csi length %d data : 0x%02x ) \n", - frame_tx%1024, nr_tti_tx, N_UCI, pucch_payload, O_ACK, pucch_ack_payload, O_SR, sr_payload, csi_status, csi_payload); + frame_tx%1024, nr_slot_tx, N_UCI, pucch_payload, O_ACK, pucch_ack_payload, O_SR, sr_payload, csi_status, csi_payload); NR_TST_PHY_PRINTF("PUCCH ( format : %d ) ( modulation : %s ) ( nb prb : %d ) ( nb symbols total: %d ) ( nb symbols : %d ) ( max code rate*100 : %d ) ( starting_symbol_index : %d ) \n", format, (Q_m == BITS_PER_SYMBOL_QPSK ? " QPSK " : " BPSK "), nb_of_prbs, nb_symbols_total, nb_symbols, max_code_rate, starting_symbol_index); @@ -561,8 +612,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ O_CRC, n_HARQ_ACK); /* set tx power */ - ue->tx_power_dBm[nr_tti_tx] = pucch_tx_power; - ue->tx_total_RE[nr_tti_tx] = nb_of_prbs*N_SC_RB; + ue->tx_power_dBm[nr_slot_tx] = pucch_tx_power; + ue->tx_total_RE[nr_slot_tx] = nb_of_prbs*N_SC_RB; int tx_amp; @@ -584,7 +635,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping, mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId[0], tx_amp, - nr_tti_tx, + nr_slot_tx, (uint8_t)m_0, (uint8_t)m_CS, nb_symbols_total, @@ -599,7 +650,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ &ue->pucch_config_dedicated[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, (uint8_t)m_0, nb_symbols_total, starting_symbol_index, @@ -620,7 +671,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ &ue->pucch_config_dedicated[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, nb_symbols_total, starting_symbol_index, nb_of_prbs, @@ -632,14 +683,14 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ case pucch_format4_nr: { nr_generate_pucch3_4(ue, - 0,//ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti, + 0,//ue->pdcch_vars[proc->thread_id][gNB_id]->crnti, ue->common_vars.txdataF, &ue->frame_parms, format, &ue->pucch_config_dedicated[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, nb_symbols_total, starting_symbol_index, nb_of_prbs, @@ -692,7 +743,7 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t int number_harq_feedback = 0; uint32_t dai_current = 0; uint32_t dai_max = 0; - int number_pid_dl = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->number_harq_processes_for_pdsch; + int number_pid_dl = ue->dlsch[proc->thread_id][gNB_id][0]->number_harq_processes_for_pdsch; bool two_transport_blocks = FALSE; int number_of_code_word = 1; int U_DAI_c = 0; @@ -725,7 +776,7 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t harq_status = &ue->dlsch[thread_idx][gNB_id][code_word]->harq_processes[dl_harq_pid]->harq_ack; /* check if current tx slot should transmit downlink acknowlegment */ - if (harq_status->slot_for_feedback_ack == proc->nr_tti_tx) { + if (harq_status->slot_for_feedback_ack == proc->nr_slot_tx) { if (harq_status->ack == DL_ACKNACK_NO_SET) { LOG_E(PHY,"PUCCH Downlink acknowledgment has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); @@ -986,7 +1037,10 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8 current_resource_id = r_PUCCH; } else { - current_resource_id = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.array[pucch_resource_indicator][0]; + if (pucch_resource_set_id !=0 ) + current_resource_id = 3; //TBC mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.array[pucch_resource_indicator][0]; + else + current_resource_id = 1; } } @@ -1050,7 +1104,7 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8 int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size) { int pucch_resource_set_id = 0; - long *pucch_max_pl_bits = NULL; + //long *pucch_max_pl_bits = NULL; /* from TS 38.331 field maxPayloadMinus1 -- Maximum number of payload bits minus 1 that the UE may transmit using this PUCCH resource set. In a PUCCH occurrence, the UE @@ -1062,9 +1116,15 @@ int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size) /* look for the first resource set which supports uci_size number of bits for payload */ while (pucch_resource_set_id < MAX_NB_OF_PUCCH_RESOURCE_SETS) { if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id] != NULL) { - pucch_max_pl_bits = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->maxPayloadSize; - if (uci_size <= (((pucch_max_pl_bits != NULL) ? *pucch_max_pl_bits : 1706) + 1)) { - NR_TST_PHY_PRINTF("PUCCH found resource set %d \n", pucch_resource_set_id); + //pucch_max_pl_bits = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->maxPayloadMinus1; + if (uci_size <= 2) { //TBC rrc (((pucch_max_pl_bits != NULL) ? *pucch_max_pl_bits : 1706) + 1)) { + //NR_TST_PHY_PRINTF("PUCCH found resource set %d max bits %d\n", pucch_resource_set_id, pucch_max_pl_bits); + pucch_resource_set_id = 0; + return (pucch_resource_set_id); + break; + } + else { + pucch_resource_set_id = 1; return (pucch_resource_set_id); break; } @@ -1096,7 +1156,7 @@ boolean_t check_pucch_format(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, pucch_format { pucch_format_nr_t selected_pucch_format; pucch_format_nr_t selected_pucch_format_second; - NR_SetupRelease_PUCCH_FormatConfig_t *identified_format = NULL; + /*NR_SetupRelease_PUCCH_FormatConfig_t *identified_format = NULL; switch (format_pucch) { case pucch_format1_nr: @@ -1121,12 +1181,12 @@ boolean_t check_pucch_format(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, pucch_format default: break; - } + }*/ - if ((identified_format != NULL) && (identified_format->choice.setup->nrofSlots[0] != 1)) { + /* if ((identified_format != NULL) && (identified_format->choice.setup->nrofSlots[0] != 1)) { LOG_E(PHY,"PUCCH not implemented multislots transmission : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); return (FALSE); - } + }*/ if (nb_symbols_for_tx <= 2) { if (uci_size <= 2) { @@ -1217,8 +1277,8 @@ int trigger_periodic_scheduling_request(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_n return (1); /* period is slot */ } - int16_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * ue->frame_parms.slots_per_subframe;//ttis_per_subframe; - if (((proc->frame_tx * N_slot_frame) + proc->nr_tti_tx - SR_offset)%SR_periodicity == 0) { + int16_t N_slot_frame = ue->frame_parms.slots_per_frame; + if (((proc->frame_tx * N_slot_frame) + proc->nr_slot_tx - SR_offset)%SR_periodicity == 0) { return (1); } else { @@ -1247,19 +1307,68 @@ uint32_t dummy_csi_payload = 0; /* FFS TODO_NR code that should be developed */ -int get_csi_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint32_t *csi_payload) +uint16_t get_nr_csi_bitlen(NR_UE_MAC_INST_t *mac) { + + uint16_t csi_bitlen =0; + uint16_t rsrp_bitlen = 0; + uint16_t diff_rsrp_bitlen = 0; + uint16_t nb_ssbri_cri = 0; + uint16_t cri_ssbri_bitlen = 0; + + NR_CSI_MeasConfig_t *csi_MeasConfig = mac->scg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + struct NR_CSI_ResourceConfig__csi_RS_ResourceSetList__nzp_CSI_RS_SSB * nzp_CSI_RS_SSB = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[0]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB; + + uint16_t nb_csi_ssb_report = nzp_CSI_RS_SSB->csi_SSB_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.count:0; + + if (0 != nb_csi_ssb_report){ + uint8_t nb_ssb_resources =0; + + if (NULL != csi_MeasConfig->csi_ReportConfigToAddModList->list.array[0]->groupBasedBeamReporting.choice.disabled->nrofReportedRS) + nb_ssbri_cri = *(csi_MeasConfig->csi_ReportConfigToAddModList->list.array[0]->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1; + else + nb_ssbri_cri = 1; + + nb_ssb_resources = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[0]->csi_SSB_ResourceList.list.count; + + if (nb_ssb_resources){ + cri_ssbri_bitlen =ceil(log2 (nb_ssb_resources)); + rsrp_bitlen = 7; + diff_rsrp_bitlen = 4; + } + else{ + cri_ssbri_bitlen =0; + rsrp_bitlen = 0; + diff_rsrp_bitlen = 0; + } + + csi_bitlen = ((cri_ssbri_bitlen * nb_ssbri_cri) + rsrp_bitlen +(diff_rsrp_bitlen *(nb_ssbri_cri -1 ))) *nb_csi_ssb_report; + + //printf("get csi bitlen %d nb_ssbri_cri %d nb_csi_report %d nb_resources %d\n", csi_bitlen,nb_ssbri_cri ,nb_csi_ssb_report, nb_ssb_resources); + } + return csi_bitlen; +} + +int get_csi_nr(NR_UE_MAC_INST_t *mac, PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint32_t *csi_payload) { VOID_PARAMETER ue; VOID_PARAMETER gNB_id; + float rsrp_db[7]; + int nElem = 98; + int rsrp_offset = 17; + int csi_status = 0; + + csi_status = get_nr_csi_bitlen(mac); + rsrp_db[0] = get_nr_RSRP(0,0,0); - if (dummy_csi_status == 0) { + + if (csi_status == 0) { *csi_payload = 0; } else { - *csi_payload = dummy_csi_payload; + *csi_payload = binary_search_float_nr(RSRP_meas_mapping_nr,nElem, rsrp_db[0]) + rsrp_offset; } - return (dummy_csi_status); + return (csi_status); } /* FFS TODO_NR code that should be removed */ @@ -1326,6 +1435,9 @@ int get_ics_pucch(NR_PUCCH_Resource_t *pucch_resource, pucch_format_nr_t format_ case pucch_format1_nr: return pucch_resource->format.choice.format1->initialCyclicShift; + + case pucch_format2_nr: + return 0; default: return -1; diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h index 089fae9f55..9b53331f50 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h @@ -60,6 +60,111 @@ /************** VARIABLES *****************************************/ +float RSRP_meas_mapping_nr[98] +#ifdef INIT_VARIABLES_PUCCH_UE_NR_H += { + -140, + -139, + -138, + -137, + -136, + -135, + -134, + -133, + -132, + -131, + -130, + -129, + -128, + -127, + -126, + -125, + -124, + -123, + -122, + -121, + -120, + -119, + -118, + -117, + -116, + -115, + -114, + -113, + -112, + -111, + -110, + -109, + -108, + -107, + -106, + -105, + -104, + -103, + -102, + -101, + -100, + -99, + -98, + -97, + -96, + -95, + -94, + -93, + -92, + -91, + -90, + -89, + -88, + -87, + -86, + -85, + -84, + -83, + -82, + -81, + -80, + -79, + -78, + -77, + -76, + -75, + -74, + -73, + -72, + -71, + -70, + -69, + -68, + -67, + -66, + -65, + -64, + -63, + -62, + -61, + -60, + -59, + -58, + -57, + -56, + -55, + -54, + -53, + -52, + -51, + -50, + -49, + -48, + -47, + -46, + -45, + -44, + -43 + } + #endif + ; + /* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */ const initial_pucch_resource_t initial_pucch_resource[NB_INITIAL_PUCCH_RESOURCE] #ifdef INIT_VARIABLES_PUCCH_UE_NR_H @@ -226,12 +331,14 @@ int trigger_periodic_scheduling_request(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_n @param csi_payload is updated with CSI @returns number of bits of CSI */ -int get_csi_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint32_t *csi_payload); +int get_csi_nr(NR_UE_MAC_INST_t *mac, PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint32_t *csi_payload); /** \brief This dummy function sets current CSI for simulation @param csi_status @param csi_payload is updated with CSI @returns none */ + +uint16_t get_nr_csi_bitlen(NR_UE_MAC_INST_t *mac); void set_csi_nr(int csi_status, uint32_t csi_payload); diff --git a/openair1/SIMULATION/LTE_PHY/common_sim.h b/openair1/SIMULATION/LTE_PHY/common_sim.h index ff8406b0c1..796a576aed 100644 --- a/openair1/SIMULATION/LTE_PHY/common_sim.h +++ b/openair1/SIMULATION/LTE_PHY/common_sim.h @@ -1,8 +1,4 @@ -static int cmpdouble(const void *p1, const void *p2) { - return *(double *)p1 > *(double *)p2; -} - double median(varArray_t *input) { return *(double *)((uint8_t *)(input+1)+(input->size/2)*input->atomSize); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 94214ab3b3..12aace577c 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -79,6 +79,9 @@ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ double DS_TDL = .03; +static int cmpdouble(const void *p1, const void *p2) { + return *(double *)p1 > *(double *)p2; +} int emulate_rf = 0; int split73=0; diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 37ce3a65d6..0443cde738 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -80,6 +80,9 @@ double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */ double t_rx_min = 1000000000; /*!< \brief initial min process time for tx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ +static int cmpdouble(const void *p1, const void *p2) { + return *(double *)p1 > *(double *)p2; +} int split73=0; @@ -345,7 +348,7 @@ int main(int argc, char **argv) { unsigned short input_buffer_length; unsigned int ret; unsigned int coded_bits_per_codeword,nsymb; - unsigned int tx_lev=0,tx_lev_dB,trials,errs[4]= {0,0,0,0},round_trials[4]= {0,0,0,0}; + unsigned int tx_lev=0,tx_lev_dB,trials,errs[5]= {0,0,0,0,0},round_trials[4]= {0,0,0,0}; FILE *bler_fd=NULL; char bler_fname[512]; FILE *time_meas_fd=NULL; diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 957495181a..c60bc8dd9f 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -52,6 +52,7 @@ PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; +UE_nr_rxtx_proc_t proc; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; @@ -559,7 +560,7 @@ int main(int argc, char **argv) vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_IN); - ret = nr_dlsch_decoding(UE, channel_output_fixed, &UE->frame_parms, + ret = nr_dlsch_decoding(UE, &proc, 0, channel_output_fixed, &UE->frame_parms, dlsch0_ue, dlsch0_ue->harq_processes[0], frame, nb_symb_sch, slot,harq_pid, is_crnti, llr8_flag); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 779a3a8dce..2ca8dae279 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -66,8 +66,9 @@ #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) #include "SIMULATION/LTE_PHY/common_sim.h" +#include +#include -unsigned char NB_eNB_INST=0; LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; rlc_info_t Rlc_info_um,Rlc_info_am_config; @@ -81,7 +82,6 @@ double cpuf; int sf_ahead=4 ; int sl_ahead=0; uint8_t nfapi_mode = 0; -uint16_t NB_UE_INST = 1; uint64_t downlink_frequency[MAX_NUM_CCs][4]; // dummy functions @@ -150,6 +150,42 @@ int is_x2ap_enabled(void) openair0_config_t openair0_cfg[MAX_CARDS]; +/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of + dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */ +int g_mcsIndex = -1, g_rbStart = -1, g_rbSize = -1; +void nr_dlsim_preprocessor(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd) { + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + AssertFatal(UE_info->num_UEs == 1, "can have only a single UE\n"); + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[0]; + + /* manually set free CCE to 0 */ + const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss); + uint8_t nr_of_candidates; + find_aggregation_candidates(&sched_ctrl->aggregation_level, + &nr_of_candidates, + sched_ctrl->search_space); + sched_ctrl->coreset = get_coreset( + sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); + sched_ctrl->cce_index = 0; + + /* set "any" value for PUCCH (simulator evaluates PDSCH only) */ + sched_ctrl->pucch_sched_idx = 0; + sched_ctrl->pucch_occ_idx = 0; + + sched_ctrl->rbStart = g_rbStart; + sched_ctrl->rbSize = g_rbSize; + sched_ctrl->mcs = g_mcsIndex; + sched_ctrl->time_domain_allocation = 2; + sched_ctrl->mcsTableIdx = 0; + AssertFatal(sched_ctrl->rbStart >= 0, "invalid rbStart %d\n", sched_ctrl->rbStart); + AssertFatal(sched_ctrl->rbSize > 0, "invalid rbSize %d\n", sched_ctrl->rbSize); + AssertFatal(sched_ctrl->mcs >= 0, "invalid sched_ctrl->mcs %d\n", sched_ctrl->mcs); + sched_ctrl->numDmrsCdmGrpsNoData = 1; +} int main(int argc, char **argv) @@ -194,11 +230,10 @@ int main(int argc, char **argv) SCM_t channel_model=AWGN;//Rayleigh1_anticorr; + NB_UE_INST = 1; //double pbch_sinr; //int pbch_tx_ant; int N_RB_DL=106,mu=1; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t dlsch_config; - NR_sched_pucch pucch_sched; //unsigned char frame_type = 0; @@ -227,7 +262,6 @@ int main(int argc, char **argv) randominit(0); - int mcsIndex_set=0,rbStart_set=0,rbSize_set=0; int print_perf = 0; FILE *scg_fd=NULL; @@ -393,18 +427,15 @@ int main(int argc, char **argv) case 'a': - dlsch_config.rbStart = atoi(optarg); - rbStart_set=1; + g_rbStart = atoi(optarg); break; case 'b': - dlsch_config.rbSize = atoi(optarg); - rbSize_set=1; + g_rbSize = atoi(optarg); break; case 'e': - dlsch_config.mcsIndex[0] = atoi(optarg); - mcsIndex_set=1; + g_mcsIndex = atoi(optarg); break; case 'm': @@ -483,6 +514,7 @@ int main(int argc, char **argv) RC.nb_nr_mac_CC[i] = 1; mac_top_init_gNB(); gNB_mac = RC.nrmac[0]; + gNB_mac->pre_processor_dl = nr_dlsim_preprocessor; gNB_RRC_INST rrc; memset((void*)&rrc,0,sizeof(rrc)); @@ -537,13 +569,14 @@ int main(int argc, char **argv) uint64_t ssb_bitmap; fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu); + fix_scc(scc,ssb_bitmap); + fill_default_secondaryCellGroup(scc, secondaryCellGroup, 0, 1, n_tx, 0); - fix_scc(scc,ssb_bitmap); xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); @@ -559,6 +592,12 @@ int main(int argc, char **argv) // nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); // call MAC to configure common parameters + /* rrc_mac_config_req_gNB() has created one user, so set the scheduling + * parameters from command line in global variables that will be picked up by + * scheduling preprocessor */ + if (g_mcsIndex < 0) g_mcsIndex = 9; + if (g_rbStart < 0) g_rbStart=0; + if (g_rbSize < 0) g_rbSize = N_RB_DL - g_rbStart; double fs,bw; @@ -647,7 +686,6 @@ int main(int argc, char **argv) else {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;} UE->perfect_ce = 0; - for (i=0;i<10;i++) UE->current_thread_id[i] = 0; if (init_nr_ue_signal(UE, 1, 0) != 0) { @@ -686,11 +724,6 @@ int main(int argc, char **argv) AssertFatal(input_fd==NULL,"Not ready for input signal file\n"); gNB->pbch_configured = 1; gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234; - - if (mcsIndex_set==0) dlsch_config.mcsIndex[0]=9; - - if (rbStart_set==0) dlsch_config.rbStart=0; - if (rbSize_set==0) dlsch_config.rbSize=N_RB_DL-dlsch_config.rbStart; //Configure UE rrc.carrier.MIB = (uint8_t*) malloc(4); @@ -714,7 +747,7 @@ int main(int argc, char **argv) scheduled_response.CC_id = 0; scheduled_response.frame = frame; scheduled_response.slot = slot; - + scheduled_response.thread_id = UE_proc.thread_id; nr_ue_phy_config_request(&UE_mac->phy_config); NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info; @@ -753,14 +786,14 @@ int main(int argc, char **argv) //multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0); UE->rx_offset=0; - UE_proc.frame_rx = frame; - UE_proc.nr_tti_rx= slot; - UE_proc.subframe_rx = slot; + UE_proc.thread_id = 0; + UE_proc.frame_rx = frame; + UE_proc.nr_slot_rx = slot; dcireq.frame = frame; dcireq.slot = slot; - NR_UE_DLSCH_t *dlsch0 = UE->dlsch[UE->current_thread_id[UE_proc.nr_tti_rx]][0][0]; + NR_UE_DLSCH_t *dlsch0 = UE->dlsch[UE_proc.thread_id][0][0]; int harq_pid = slot; NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid]; @@ -787,8 +820,14 @@ int main(int argc, char **argv) for (int i=0; iUE_info.num_pdcch_cand[0][i] = 0; - if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&pucch_sched,&dlsch_config); - else nr_schedule_css_dlsch_phytest(0,frame,slot); + if (css_flag == 0) { + const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160}; + const NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; + const int num_slots_per_tdd = slots_per_frame[*scc->ssbSubcarrierSpacing] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity); + nr_schedule_ue_spec(0, frame, slot, num_slots_per_tdd); + } else { + nr_schedule_css_dlsch_phytest(0,frame,slot); + } Sched_INFO.module_id = 0; Sched_INFO.CC_id = 0; Sched_INFO.frame = frame; @@ -824,38 +863,11 @@ int main(int argc, char **argv) 12, frame_parms->nb_prefix_samples, CYCLIC_PREFIX); - } else {/* + } else { nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset], &txdata[aa][tx_offset], 14, frame_parms); - */ - PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset], - (int*)&txdata[aa][tx_offset], - frame_parms->ofdm_symbol_size, - 1, - frame_parms->nb_prefix_samples0, - CYCLIC_PREFIX); - - apply_nr_rotation(frame_parms, - (int16_t*)&txdata[aa][tx_offset], - slot, - 0, - 1, - frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0); - PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset+frame_parms->ofdm_symbol_size], - (int*)&txdata[aa][tx_offset+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size], - frame_parms->ofdm_symbol_size, - 13, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); - apply_nr_rotation(frame_parms, - (int16_t*)&txdata[aa][tx_offset+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size], - slot, - 1, - 13, - frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples); - } } @@ -913,21 +925,21 @@ int main(int argc, char **argv) //---------------------------------------------------------- //---------------------- count errors ---------------------- //---------------------------------------------------------- - - if (UE->dlsch[UE->current_thread_id[slot]][0][0]->last_iteration_cnt >= - UE->dlsch[UE->current_thread_id[slot]][0][0]->max_ldpc_iterations+1) + + if (UE->dlsch[UE_proc.thread_id][0][0]->last_iteration_cnt >= + UE->dlsch[UE_proc.thread_id][0][0]->max_ldpc_iterations+1) n_errors++; - - NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]]; + + NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE_proc.thread_id]; int16_t *UE_llr = pdsch_vars[0]->llr[0]; - + TBS = UE_harq_process->TBS;//rel15->TBSize[0]; uint16_t length_dmrs = 1; uint16_t nb_rb = rel15->rbSize; uint8_t nb_re_dmrs = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4; uint8_t mod_order = rel15->qamModOrder[0]; uint8_t nb_symb_sch = rel15->NrOfSymbols; - + available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers); for (i = 0; i < available_bits; i++) { @@ -985,7 +997,7 @@ int main(int argc, char **argv) if (print_perf==1) { printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, TBS %d, Kr %d (Zc %d))\n", - 1000>>*scc->ssbSubcarrierSpacing,dlsch_config.rbSize,dlsch_config.mcsIndex[0], + 1000>>*scc->ssbSubcarrierSpacing, g_rbSize, g_mcsIndex, gNB->dlsch[0][0]->harq_processes[0]->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3, gNB->dlsch[0][0]->harq_processes[0]->K, gNB->dlsch[0][0]->harq_processes[0]->K/((gNB->dlsch[0][0]->harq_processes[0]->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3)>3824?22:10)); @@ -1017,9 +1029,9 @@ int main(int argc, char **argv) printStatIndent(&UE->dlsch_unscrambling_stats,"DLSCH unscrambling time"); printStatIndent(&UE->dlsch_rate_unmatching_stats,"DLSCH Rate Unmatching"); printf("|__ DLSCH Turbo Decoding(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, + UE->dlsch[UE_proc.thread_id][0][0]->harq_processes[0]->Cminus ? + UE->dlsch[UE_proc.thread_id][0][0]->harq_processes[0]->Kminus : + UE->dlsch[UE_proc.thread_id][0][0]->harq_processes[0]->Kplus, UE->dlsch_tc_intl1_stats.trials/(double)UE->dlsch_tc_init_stats.trials, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials*timeBase, (int)((double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials), @@ -1041,7 +1053,7 @@ int main(int argc, char **argv) LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1); LOG_M("chestF0.m","chF0",UE->pdsch_vars[0][0]->dl_ch_estimates_ext,N_RB_DL*12*14,1,1); write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1); - LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]][0]->llr[0],available_bits,1,0); + LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE_proc.thread_id][0]->llr[0],available_bits,1,0); break; } diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 833b81f853..2a7c51a582 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -35,6 +35,7 @@ #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/MODULATION/modulation_UE.h" +#include "PHY/MODULATION/nr_modulation.h" #include "PHY/INIT/phy_init.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" @@ -45,6 +46,7 @@ #include "openair1/SIMULATION/RF/rf.h" #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" +#include "openair1/PHY/MODULATION/nr_modulation.h" //#define DEBUG_NR_PBCHSIM @@ -678,6 +680,7 @@ int main(int argc, char **argv) if (ret<0) n_errors++; } else { + UE_nr_rxtx_proc_t proc={0}; UE->rx_offset=0; uint8_t ssb_index = 0; while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb @@ -686,16 +689,16 @@ int main(int argc, char **argv) int ssb_slot = (ssb_index>>1)+(n_hf*frame_parms->slots_per_frame); for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) { - nr_slot_fep(UE, - i%frame_parms->symbols_per_slot, - ssb_slot, - 0, - 0); + nr_slot_fep(UE, + &proc, + i%frame_parms->symbols_per_slot, + ssb_slot, + 0, + 0); - nr_pbch_channel_estimation(UE,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf); + nr_pbch_channel_estimation(UE,&proc,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf); } - UE_nr_rxtx_proc_t proc={0}; ret = nr_rx_pbch(UE, &proc, diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index cee04c1e57..0cc7e9f08a 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -45,11 +45,13 @@ #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "nr_unitary_defs.h" #include "OCG_vars.h" +#include +#include + #define NR_PRACH_DEBUG 1 #define PRACH_WRITE_OUTPUT_DEBUG 1 -unsigned char NB_eNB_INST=0; LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; rlc_info_t Rlc_info_um,Rlc_info_am_config; @@ -59,7 +61,6 @@ RAN_CONTEXT_t RC; RU_t *ru; double cpuf; extern uint16_t prach_root_sequence_map0_3[838]; -uint16_t NB_UE_INST=1; openair0_config_t openair0_cfg[MAX_CARDS]; uint8_t nfapi_mode=0; int sl_ahead = 0; @@ -115,15 +116,16 @@ int main(int argc, char **argv){ int i, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1; int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0; uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0; - uint8_t frame = 1, subframe = 9, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, num_root_sequences = 16, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol; + uint8_t frame = 1, subframe = 9, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol; uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1; - uint32_t tx_lev = 10000, prach_errors = 0, samp_count; //,tx_lev_dB; + uint32_t tx_lev = 10000, prach_errors = 0; //,tx_lev_dB; uint64_t SSB_positions = 0x01, absoluteFrequencyPointA = 640000; uint16_t RA_sfn_index; uint8_t N_RA_slot; uint8_t config_period; int prachOccasion = 0; double DS_TDL = .03; + NB_UE_INST=1; // int8_t interf1=-19,interf2=-19; // uint8_t abstraction_flag=0,calibration_flag=0; @@ -625,8 +627,8 @@ int main(int argc, char **argv){ subframe); */ //commented for testing purpose UE_nr_rxtx_proc_t proc={0}; - proc.frame_tx = frame; - proc.nr_tti_tx = slot; + proc.frame_tx = frame; + proc.nr_slot_tx = slot; nr_ue_prach_procedures(UE,&proc,0,0); /* tx_lev_dB not used later, no need to set */ @@ -703,7 +705,7 @@ int main(int argc, char **argv){ // printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB); if (awgn_flag == 0) { - multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_tti<<1, 0); + multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_frame, 0); } if (n_frames==1) { diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index c14a3d7198..a96a62f656 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -90,7 +90,7 @@ int main(int argc, char **argv) FILE *input_fd=NULL; //uint8_t nacktoack_flag=0; int16_t amp=0x7FFF; - int nr_tti_tx=0; + int nr_slot_tx=0; uint64_t actual_payload=0,payload_received; int nr_bit=1; // maximum value possible is 2 uint8_t m0=0;// higher layer paramater initial cyclic shift @@ -501,13 +501,13 @@ int main(int argc, char **argv) for (trial=0; trialofdm_symbol_size*sizeof(int)); if(format==0){ - nr_generate_pucch0(UE,txdataF,frame_parms,PUCCH_GroupHopping,hopping_id,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB); + nr_generate_pucch0(UE,txdataF,frame_parms,PUCCH_GroupHopping,hopping_id,amp,nr_slot_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB); } else if (format == 1){ - nr_generate_pucch1(UE,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit); + nr_generate_pucch1(UE,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit); } else { - nr_generate_pucch2(UE,0x1234,dmrs_scrambling_id,data_scrambling_id,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,nrofSymbols,startingSymbolIndex,nrofPRB,startingPRB,nr_bit); + nr_generate_pucch2(UE,0x1234,dmrs_scrambling_id,data_scrambling_id,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,nrofSymbols,startingSymbolIndex,nrofPRB,startingPRB,nr_bit); } int txlev = signal_energy(&txdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size], @@ -536,21 +536,21 @@ int main(int argc, char **argv) if (n_trials==1) printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12)); if(format==0){ - nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu; - nfapi_nr_pucch_pdu_t pucch_pdu; - pucch_pdu.subcarrier_spacing = 1; - pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1; - pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1; - pucch_pdu.bit_len_harq = nr_bit; - pucch_pdu.bit_len_csi_part1 = 0; - pucch_pdu.bit_len_csi_part2 = 0; - pucch_pdu.sr_flag = sr_flag; - pucch_pdu.nr_of_symbols = nrofSymbols; - pucch_pdu.hopping_id = hopping_id; - pucch_pdu.initial_cyclic_shift = 0; - pucch_pdu.start_symbol_index = startingSymbolIndex; - pucch_pdu.prb_start = startingPRB; - nr_decode_pucch0(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu); + nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu; + nfapi_nr_pucch_pdu_t pucch_pdu; + pucch_pdu.subcarrier_spacing = 1; + pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1; + pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1; + pucch_pdu.bit_len_harq = nr_bit; + pucch_pdu.bit_len_csi_part1 = 0; + pucch_pdu.bit_len_csi_part2 = 0; + pucch_pdu.sr_flag = sr_flag; + pucch_pdu.nr_of_symbols = nrofSymbols; + pucch_pdu.hopping_id = hopping_id; + pucch_pdu.initial_cyclic_shift = 0; + pucch_pdu.start_symbol_index = startingSymbolIndex; + pucch_pdu.prb_start = startingPRB; + nr_decode_pucch0(gNB,nr_slot_tx,&uci_pdu,&pucch_pdu); if(sr_flag==1){ if (uci_pdu.sr->sr_indication == 0 || uci_pdu.sr->sr_confidence_level == 1) sr_errors+=1; @@ -565,7 +565,7 @@ int main(int argc, char **argv) } else if (format==1) { nr_decode_pucch1(rxdataF,PUCCH_GroupHopping,hopping_id, - &(payload_received),frame_parms,amp,nr_tti_tx, + &(payload_received),frame_parms,amp,nr_slot_tx, m0,nrofSymbols,startingSymbolIndex,startingPRB, startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); if(nr_bit==1) @@ -574,34 +574,34 @@ int main(int argc, char **argv) ack_nack_errors+=((actual_payload^payload_received)&1) + (((actual_payload^payload_received)&2)>>1); } else if (format==2) { - nfapi_nr_uci_pucch_pdu_format_2_3_4_t uci_pdu; - nfapi_nr_pucch_pdu_t pucch_pdu; - pucch_pdu.rnti = 0x1234; - pucch_pdu.subcarrier_spacing = 1; - pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1; - pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1; - pucch_pdu.bit_len_csi_part1 = nr_bit; - pucch_pdu.bit_len_harq = 0; - pucch_pdu.bit_len_csi_part2 = 0; - pucch_pdu.sr_flag = 0; - pucch_pdu.nr_of_symbols = nrofSymbols; - pucch_pdu.hopping_id = hopping_id; - pucch_pdu.initial_cyclic_shift = 0; - pucch_pdu.start_symbol_index = startingSymbolIndex; - pucch_pdu.prb_size = nrofPRB; - pucch_pdu.prb_start = startingPRB; - pucch_pdu.dmrs_scrambling_id = dmrs_scrambling_id; - pucch_pdu.data_scrambling_id = data_scrambling_id; - nr_decode_pucch2(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu); - int csi_part1_bytes=pucch_pdu.bit_len_csi_part1>>3; - if ((pucch_pdu.bit_len_csi_part1&7) > 0) csi_part1_bytes++; - for (int i=0;i>1)&1; + pucch_pdu.bit_len_csi_part1 = nr_bit; + pucch_pdu.bit_len_harq = 0; + pucch_pdu.bit_len_csi_part2 = 0; + pucch_pdu.sr_flag = 0; + pucch_pdu.nr_of_symbols = nrofSymbols; + pucch_pdu.hopping_id = hopping_id; + pucch_pdu.initial_cyclic_shift = 0; + pucch_pdu.start_symbol_index = startingSymbolIndex; + pucch_pdu.prb_size = nrofPRB; + pucch_pdu.prb_start = startingPRB; + pucch_pdu.dmrs_scrambling_id = dmrs_scrambling_id; + pucch_pdu.data_scrambling_id = data_scrambling_id; + nr_decode_pucch2(gNB,nr_slot_tx,&uci_pdu,&pucch_pdu); + int csi_part1_bytes=pucch_pdu.bit_len_csi_part1>>3; + if ((pucch_pdu.bit_len_csi_part1&7) > 0) csi_part1_bytes++; + for (int i=0;i>1)+(((actual_payload^payload_received)&4)>>2)+n_errors; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 5494e64eca..19b107a80a 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -60,9 +60,11 @@ #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) #include "SIMULATION/LTE_PHY/common_sim.h" +#include +#include + //#define DEBUG_ULSIM -unsigned char NB_eNB_INST=0; LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; rlc_info_t Rlc_info_um,Rlc_info_am_config; @@ -75,7 +77,6 @@ int sf_ahead=4 ; int sl_ahead=0; double cpuf; uint8_t nfapi_mode = 0; -uint16_t NB_UE_INST = 1; uint64_t downlink_frequency[MAX_NUM_CCs][4]; @@ -164,6 +165,7 @@ int main(int argc, char **argv) uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; double tx_gain=1.0; double N0=30; + NB_UE_INST = 1; //unsigned char frame_type = 0; NR_DL_FRAME_PARMS *frame_parms; @@ -565,13 +567,14 @@ int main(int argc, char **argv) uint64_t ssb_bitmap; fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu); + fix_scc(scc,ssb_bitmap); + fill_default_secondaryCellGroup(scc, secondaryCellGroup, 0, 1, n_tx, 0); - fix_scc(scc,ssb_bitmap); // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); @@ -668,8 +671,7 @@ int main(int argc, char **argv) nr_scheduled_response_t scheduled_response; fapi_nr_ul_config_request_t ul_config; fapi_nr_tx_request_t tx_req; - fapi_nr_tx_request_body_t tx_req_body; - + uint8_t ptrs_mcs1 = 2; uint8_t ptrs_mcs2 = 4; uint8_t ptrs_mcs3 = 10; @@ -831,7 +833,8 @@ int main(int argc, char **argv) gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round; rv_index = nr_rv_round_map[round]; - UE_proc.nr_tti_tx = slot; + UE_proc.thread_id = 0; + UE_proc.nr_slot_tx = slot; UE_proc.frame_tx = frame; UL_tti_req->SFN = frame; @@ -902,19 +905,19 @@ int main(int argc, char **argv) scheduled_response.CC_id = 0; scheduled_response.frame = frame; scheduled_response.slot = slot; + scheduled_response.thread_id = UE_proc.thread_id; scheduled_response.dl_config = NULL; scheduled_response.ul_config = &ul_config; scheduled_response.tx_request = &tx_req; - scheduled_response.tx_request->tx_request_body = &tx_req_body; - + // Config UL TX PDU tx_req.slot = slot; tx_req.sfn = frame; // tx_req->tx_config // TbD tx_req.number_of_pdus = 1; - tx_req_body.pdu_length = TBS/8; - tx_req_body.pdu_index = 0; - tx_req_body.pdu = &ulsch_input_buffer[0]; + tx_req.tx_request_body[0].pdu_length = TBS/8; + tx_req.tx_request_body[0].pdu_index = 0; + tx_req.tx_request_body[0].pdu = &ulsch_input_buffer[0]; ul_config.slot = slot; ul_config.number_pdus = 1; @@ -958,7 +961,7 @@ int main(int argc, char **argv) /////////////////////////phy_procedures_nr_ue_TX/////////////////////// /////////// - phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0); + phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id); if (n_trials==1) { diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c index 1ab935fcae..c88c261667 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c @@ -51,16 +51,16 @@ void display_frame_configuration(NR_DL_FRAME_PARMS *frame_parms) { - printf("\nTdd configuration tti %d downlink %d uplink %d period %d \n", frame_parms->ttis_per_subframe, frame_parms->p_tdd_UL_DL_Configuration->nrofDownlinkSlots, + printf("\nTdd configuration tti %d downlink %d uplink %d period %d \n", frame_parms->slots_per_subframe, frame_parms->p_tdd_UL_DL_Configuration->nrofDownlinkSlots, frame_parms->p_tdd_UL_DL_Configuration->nrofUplinkSlots, frame_parms->p_tdd_UL_DL_Configuration->dl_UL_TransmissionPeriodicity); int k = (TDD_CONFIG_NB_FRAMES * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) - 1; //19; int tti = 0; - for (int j = 0; j < TDD_CONFIG_NB_FRAMES * frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; j++) { + for (int j = 0; j < TDD_CONFIG_NB_FRAMES * frame_parms->slots_per_frame; j++) { int frame = 0; if (j != 0) { - frame = (frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME)/j; - tti = (j)%(frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME); + frame = j / frame_parms->slots_per_frame; + tti = j % frame_parms->slots_per_frame; } else { frame = 0; @@ -99,9 +99,10 @@ void display_frame_configuration(NR_DL_FRAME_PARMS *frame_parms) { * *********************************************************************/ -void set_tti_test(NR_DL_FRAME_PARMS *frame_parms, int ttis_per_subframe) +void set_tti_test(NR_DL_FRAME_PARMS *frame_parms, int slots_per_subframe) { - frame_parms->ttis_per_subframe = ttis_per_subframe; + frame_parms->slots_per_subframe = slots_per_subframe; + frame_parms->slots_per_frame = slots_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; } /******************************************************************* diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c index fc5360848c..7600dfb08f 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c @@ -94,6 +94,7 @@ extern int pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode); int test_synchro_pss_sss_nr(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int pss_sequence_number) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); + UE_nr_rxtx_proc_t proc = {0}; int synchro_position; int offset; int16_t *tmp; @@ -130,7 +131,7 @@ int test_synchro_pss_sss_nr(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, in #endif - rx_sss_nr(PHY_vars_UE, &metric_fdd_ncp, &phase_fdd_ncp); + rx_sss_nr(PHY_vars_UE, &proc, &metric_fdd_ncp, &phase_fdd_ncp); #if TEST_SYNCHRO_TIMING_PSS @@ -244,7 +245,7 @@ void set_sequence_sss(PHY_VARS_NR_UE *PHY_vars_UE, int offset, int slot_offset) void insert_sequence_sss(PHY_VARS_NR_UE *PHY_vars_UE, int offset) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); - int samples_for_half_frame = (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)>>1; + int samples_for_half_frame = frame_parms->samples_per_frame / 2; set_sequence_sss(PHY_vars_UE, offset, 0); @@ -327,7 +328,7 @@ int test_synchro_pss_sss(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int s int sync_pos2 = synchro_position - frame_parms->nb_prefix_samples; - int sync_pos_slot = (frame_parms->samples_per_tti>>1) - frame_parms->ofdm_symbol_size - frame_parms->nb_prefix_samples; + int sync_pos_slot = (frame_parms->samples_per_slot>>1) - frame_parms->ofdm_symbol_size - frame_parms->nb_prefix_samples; if (sync_pos2 >= sync_pos_slot) PHY_vars_UE->rx_offset = sync_pos2 - sync_pos_slot; diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c index fa8b49842f..f3dbc78a73 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c @@ -300,7 +300,7 @@ typedef enum { void set_random_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int amp) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); - int samples_for_frame = (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti); + int samples_for_frame = frame_parms->samples_per_frame; int16_t random; int16_t *data_p; random_data_format_t data_format = SINUSOIDAL_DATA; @@ -394,7 +394,7 @@ void set_random_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int amp) { int set_pss_in_rx_buffer_from_external_buffer(PHY_VARS_NR_UE *PHY_vars_UE, short *input_buffer) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); - int samples_for_frame = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe; /* both i and q */ + int samples_for_frame = frame_parms->samples_per_frame; /* both i and q */ for (int aa=0; aaframe_parms.nb_antennas_rx; aa++) { for (int i = 0; i < samples_for_frame; i++) { diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h index 65755b0dfb..f0929e88c0 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h @@ -69,12 +69,6 @@ typedef struct { int number_of_fail; } test_t; -typedef struct { - uint16_t ofdm_symbol_size; - uint32_t samples_per_tti; - uint32_t samples_per_subframe; -} save_frame_parms_t; - /*************** GLOBAL VARIABLES***********************************/ EXTERN PHY_VARS_eNB *PHY_vars_eNB; diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c index ab3ede4b8f..68acea6d98 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c @@ -58,7 +58,7 @@ int test_pucch_generators(PHY_VARS_NR_UE *ue) { int occ_Index = 0; uint64_t pucch_payload = 0; int tx_amp = 512; - int nr_tti_tx = 0; + int nr_slot_tx = 0; int N_UCI = 0; /* size in bits for Uplink Control Information */ switch(format) { @@ -67,7 +67,7 @@ int test_pucch_generators(PHY_VARS_NR_UE *ue) { &ue->frame_parms, &ue->pucch_config_dedicated_nr[gNB_id], tx_amp, - nr_tti_tx, + nr_slot_tx, (uint8_t)m_0, (uint8_t)m_CS, nb_symbols_total, @@ -82,7 +82,7 @@ int test_pucch_generators(PHY_VARS_NR_UE *ue) { &ue->pucch_config_dedicated_nr[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, (uint8_t)m_0, nb_symbols_total, starting_symbol_index, @@ -95,13 +95,13 @@ int test_pucch_generators(PHY_VARS_NR_UE *ue) { case pucch_format2_nr: { nr_generate_pucch2(ue, - ue->pdcch_vars[ue->current_thread_id[nr_tti_tx]][gNB_id]->crnti, + ue->pdcch_vars[thread_number][gNB_id]->crnti, ue->common_vars.txdataF, &ue->frame_parms, &ue->pucch_config_dedicated_nr[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, nb_symbols_total, starting_symbol_index, nb_of_prbs, @@ -113,14 +113,14 @@ int test_pucch_generators(PHY_VARS_NR_UE *ue) { case pucch_format3_nr: case pucch_format4_nr: { nr_generate_pucch3_4(ue, - ue->pdcch_vars[ue->current_thread_id[nr_tti_tx]][gNB_id]->crnti, + ue->pdcch_vars[thread_number][gNB_id]->crnti, ue->common_vars.txdataF, &ue->frame_parms, format, &ue->pucch_config_dedicated_nr[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, nb_symbols_total, starting_symbol_index, nb_of_prbs, diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c index ff15dec6a4..bdb860a150 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c @@ -169,7 +169,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr printf("%s", tst_separator); - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; printf("\n => Test : No harq feedback on going\n"); @@ -180,9 +180,9 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr } /* set a tx slot with no ack */ - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; printf("\n => Test : Error due to acknownlegment not set \n"); @@ -267,7 +267,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ common_pucch_configuration(ue, gNB_id, TST_PUCCH_COMMON_CONFIG_INDEX_OK); /* set a tx slot with no ack */ - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; harq_status->ack = DL_ACK; @@ -290,9 +290,9 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ /* set a second ack on a different downlink harq process */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_SECOND; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_SECOND; - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_SECOND].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_SECOND].harq_ack; harq_status->n_CCE = 2; harq_status->N_CCE = 4; @@ -300,7 +300,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ harq_status->send_harq_status = 1; harq_status->vDAI_DL = 2; harq_status->ack = DL_ACK; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; printf("\n => Test : PUCCH format from common config in dedicated mode: two positive downlink ACKnowledgments \n"); @@ -316,7 +316,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ v_return = -1; } - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack.ack = DL_NACK; + ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack.ack = DL_NACK; printf("\n => Test : PUCCH format from common config in dedicated mode: two negative downlink ACKnowledgments \n"); @@ -563,11 +563,11 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, printf("%s", tst_separator); - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = 1; harq_status->ack = DL_ACK; @@ -582,11 +582,11 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, for (int i = 0; i < TST_NB_STEP_SINGLE_TRANSPORT_BLOCK; i++) { /* set a tx slot with no ack */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = dl_harq_pid[i]; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = dl_harq_pid[i]; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = i+1; harq_status->ack = DL_ACK; @@ -616,11 +616,11 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, for (i = 1; i < TST_NB_STEP_SINGLE_TRANSPORT_BLOCK; i = i+2) { /* set a tx slot with no ack */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = dl_harq_pid[i]; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = dl_harq_pid[i]; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = i+1; harq_status->ack = DL_ACK; @@ -677,14 +677,14 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE for (int code_word = 0; code_word < 2; code_word++) { - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; + ue->dlsch[proc->thread_id][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; /* set a tx slot with no ack */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; + ue->dlsch[proc->thread_id][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = i+1; harq_status->ack = DL_ACK; @@ -697,7 +697,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE reset_harq = TRUE; } - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; harq_status->pucch_resource_indicator = pucch_resource_indicator[i][j]; @@ -720,21 +720,21 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE for (int code_word = 0; code_word < 2; code_word++) { - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; + ue->dlsch[proc->thread_id][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; /* set a tx slot with no ack */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; + ue->dlsch[proc->thread_id][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = i+1; harq_status->ack = DL_ACK; for (int j = 0 ; j < 2; j++) { - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; harq_status->pucch_resource_indicator = pucch_resource_indicator[i][j]; } @@ -754,21 +754,21 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE for (int code_word = 0; code_word < 2; code_word++) { - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; + ue->dlsch[proc->thread_id][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; /* set a tx slot with no ack */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; + ue->dlsch[proc->thread_id][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = i+1; harq_status->ack = DL_ACK; for (int j = 0 ; j < 2; j++) { - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; harq_status->pucch_resource_indicator = pucch_resource_indicator[i][j]; } @@ -935,7 +935,7 @@ int test_sr_alone_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *p } /* restore single transport block */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->Number_MCS_HARQ_DL_DCI = 1; + ue->dlsch[proc->thread_id][gNB_id][0]->Number_MCS_HARQ_DL_DCI = 1; return (v_return); } @@ -976,11 +976,11 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro NR_UE_HARQ_STATUS_t *harq_status; - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = 1; harq_status->ack = DL_ACK; @@ -1015,11 +1015,11 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro /* set a second harq ack context */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_SECOND; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_SECOND; - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_SECOND].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_SECOND].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = 2; harq_status->ack = DL_ACK; @@ -1073,7 +1073,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) printf("%s", tst_separator); - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = NR_MAX_DLSCH_HARQ_PROCESSES; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = NR_MAX_DLSCH_HARQ_PROCESSES; set_csi_nr( 4, 0x0E ); @@ -1090,11 +1090,11 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) NR_UE_HARQ_STATUS_t *harq_status; - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = 1; harq_status->ack = DL_ACK; @@ -1168,9 +1168,11 @@ int test_pucch(PHY_VARS_NR_UE *ue) assert(0); } - proc->frame_tx = 0; - proc->nr_tti_rx = 0; - proc->nr_tti_tx = (proc->nr_tti_rx + NR_UE_CAPABILITY_SLOT_RX_TO_TX)%(ue->frame_parms.ttis_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); + proc->frame_rx = 0; + proc->nr_slot_rx = 0; + + proc->frame_tx = proc->frame_rx + (proc->nr_slot_rx + NR_UE_CAPABILITY_SLOT_RX_TO_TX) / ue->frame_parms.slots_per_frame; + proc->nr_slot_tx = (proc->nr_slot_rx + NR_UE_CAPABILITY_SLOT_RX_TO_TX) % ue->frame_parms.slots_per_frame; init_pucch_power_configuration( ue, gNB_id); diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c index 0bbe7cac7f..aedb5729a3 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c @@ -223,12 +223,12 @@ int test_srs_periodicity(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc) } printf("srs period %d offset %d \n", srs_current_period, p_srs_resource->SRS_Offset); - int duration = (10 * srs_current_period)/(NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->ttis_per_subframe); + int duration = (10 * srs_current_period) / frame_parms->slots_per_frame; for (int frame_tx = 0; frame_tx < duration; frame_tx++) { - for (int slot_tx = 0; slot_tx < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->ttis_per_subframe); slot_tx++) { - proc->frame_tx = frame_tx; - proc->nr_tti_tx = slot_tx; + for (int slot_tx = 0; slot_tx < frame_parms->slots_per_frame; slot_tx++) { + proc->frame_tx = frame_tx; + proc->nr_slot_tx = slot_tx; if (ue_srs_procedure_nr( ue, proc, 0) == 0) { printf("test_srs_periodicity srs at frame %d slot %d \n", frame_tx, slot_tx); } @@ -372,7 +372,7 @@ int test_srs(PHY_VARS_NR_UE *PHY_vars_UE) /* start test of sounding reference signals */ default_srs_configuration(frame_parms); - txptr = calloc(frame_parms->samples_per_tti , sizeof(int32_t)); + txptr = calloc(frame_parms->samples_per_slot , sizeof(int32_t)); if (txptr == NULL) { printf("Error test_srs: memory allocation problem txptr \n"); assert(0); diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c index 81e232794e..34127b604f 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c @@ -84,6 +84,7 @@ int test_synchro_pss_sss_nr(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, NR_DL_FRAME_PARMS *frame_parms_gNB, test_t *test) { + UE_nr_rxtx_proc_t proc = {0}; VOID_PARAMETER test; int synchro_position; int offset; @@ -133,7 +134,7 @@ int test_synchro_pss_sss_nr(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, NR #endif - rx_sss_nr(PHY_vars_UE, &metric_fdd_ncp, &phase_fdd_ncp); + rx_sss_nr(PHY_vars_UE, &proc, &metric_fdd_ncp, &phase_fdd_ncp); #if TEST_SYNCHRO_TIMING_PSS diff --git a/openair2/COMMON/itti_sim_messages_def.h b/openair2/COMMON/itti_sim_messages_def.h index 13e170684f..681fc932dd 100644 --- a/openair2/COMMON/itti_sim_messages_def.h +++ b/openair2/COMMON/itti_sim_messages_def.h @@ -1,12 +1,31 @@ -/*! -\file itti_sim_messages_def.h +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ -\brief itti message for itti simulator -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ +/*! \file itti_sim_messages_def.h + * \brief itti message for itti simulator + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ diff --git a/openair2/COMMON/itti_sim_messages_types.h b/openair2/COMMON/itti_sim_messages_types.h index 247c474542..2e29e8f508 100644 --- a/openair2/COMMON/itti_sim_messages_types.h +++ b/openair2/COMMON/itti_sim_messages_types.h @@ -1,12 +1,31 @@ -/*! -\file itti_sim_messages_types.h +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ -\brief itti message for itti simulator -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ +/*! \file itti_sim_messages_types.h + * \brief itti message for itti simulator + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ #ifndef ITTI_SIM_MESSAGES_TYPES_H_ #define ITTI_SIM_MESSAGES_TYPES_H_ diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index af364437b8..49cb2247bf 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -65,18 +65,6 @@ #define MAX_NR_RRC_UE_CONTEXTS 64 #ifndef UE_EXPANSION - // TODO:L2 FAPI simulator. - // UESIM_EXPANSION is used to be same value of MAX_MOBILES_PER_ENB - // in eNB and UE. - // now , if we use --mu option in UE, compiling error will occur. - // This problem will be fixed in the future. - #ifdef UESIM_EXPANSION - #define MAX_MOBILES_PER_ENB 256 - #define MAX_MOBILES_PER_ENB_NB_IoT 256 - #define MAX_MOBILES_PER_GNB 256 - #define MAX_eNB 2 - #define MAX_gNB 2 - #else #ifdef LARGE_SCALE #define MAX_MOBILES_PER_ENB 128 #define MAX_MOBILES_PER_ENB_NB_IoT 128 @@ -90,7 +78,6 @@ #define MAX_eNB 2 #define MAX_gNB 2 #endif - #endif #else #define MAX_MOBILES_PER_ENB 256 #define MAX_MOBILES_PER_ENB_NB_IoT 256 diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index befab4ebdf..f6b4f3c4e2 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -386,6 +386,7 @@ typedef struct s1ap_register_enb_req_s { uint8_t nb_mme; /* List of MME to connect to */ net_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS]; + uint16_t mme_port[S1AP_MAX_NB_MME_IP_ADDRESS]; uint8_t broadcast_plmn_num[S1AP_MAX_NB_MME_IP_ADDRESS]; uint8_t broadcast_plmn_index[S1AP_MAX_NB_MME_IP_ADDRESS][PLMN_LIST_MAX_SIZE]; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index cf8ba78a81..de77d783c7 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2511,6 +2511,9 @@ int RCconfig_S1( S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = 0; } + /* set S1-mme port (sctp) */ + S1AP_REGISTER_ENB_REQ(msg_p).mme_port[l] = *S1ParamList.paramarray[l][ENB_MME_PORT_IDX].u16ptr; + AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] <= S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, "List of broadcast PLMN to be sent to MME can not be longer than actual " "PLMN list (max %d, but is %d)\n", diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index d2372c944c..de7e0bbdad 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -34,6 +34,7 @@ #define ENB_PARAMDEF_H_ #include "common/config/config_paramdesc.h" #include "RRC_paramsvalues.h" +#include "s1ap_eNB_default_values.h" #define ENB_CONFIG_STRING_CC_NODE_FUNCTION "node_function" #define ENB_CONFIG_STRING_CC_NODE_TIMING "node_timing" @@ -96,6 +97,7 @@ typedef enum { #define CONFIG_STRING_RU_OTA_SYNC_ENABLE "ota_sync_enabled" #define CONFIG_STRING_RU_BF_WEIGHTS_LIST "bf_weights" #define CONFIG_STRING_RU_IF_FREQUENCY "if_freq" +#define CONFIG_STRING_RU_IF_FREQ_OFFSET "if_offset" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -124,6 +126,7 @@ typedef enum { #define RU_OTA_SYNC_ENABLE_IDX 24 #define RU_BF_WEIGHTS_LIST_IDX 25 #define RU_IF_FREQUENCY 26 +#define RU_IF_FREQ_OFFSET 27 /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* RU configuration parameters */ @@ -157,6 +160,7 @@ typedef enum { {CONFIG_STRING_RU_OTA_SYNC_ENABLE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_BF_WEIGHTS_LIST, NULL, 0, iptr:NULL, defintarrayval:DEFBFW, TYPE_INTARRAY, 0}, \ {CONFIG_STRING_RU_IF_FREQUENCY, NULL, 0, u64ptr:NULL, defuintval:0, TYPE_UINT64, 0}, \ + {CONFIG_STRING_RU_IF_FREQ_OFFSET, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ @@ -907,6 +911,7 @@ typedef struct srb1_params_s { #define ENB_CONFIG_STRING_MME_IPV4_ADDRESS "ipv4" #define ENB_CONFIG_STRING_MME_IPV6_ADDRESS "ipv6" +#define ENB_CONFIG_STRING_MME_PORT "port" #define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE "active" #define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE "preference" #define ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX "broadcast_plmn_index" @@ -921,14 +926,20 @@ typedef struct srb1_params_s { {ENB_CONFIG_STRING_MME_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX, NULL, 0, uptr:NULL, defintarrayval:NULL, TYPE_UINTARRAY, 6} \ + {ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX, NULL, 0, uptr:NULL, defintarrayval:NULL, TYPE_UINTARRAY, 6}, \ + {ENB_CONFIG_STRING_MME_PORT, NULL, 0, u16ptr:NULL, defuintval:S1AP_PORT_NUMBER, TYPE_UINT16, 0}, \ } + + + + #define ENB_MME_IPV4_ADDRESS_IDX 0 #define ENB_MME_IPV6_ADDRESS_IDX 1 #define ENB_MME_IP_ADDRESS_ACTIVE_IDX 2 #define ENB_MME_IP_ADDRESS_PREFERENCE_IDX 3 #define ENB_MME_BROADCAST_PLMN_INDEX 4 +#define ENB_MME_PORT_IDX 5 /*---------------------------------------------------------------------------------------------------------------------------------------*/ /* X2 configuration parameters section name */ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index c66408c638..074bfb413f 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -676,13 +676,16 @@ int RCconfig_nr_gtpu(void ) { char* gnb_interface_name_for_NGU = NULL; char* gnb_ipv4_address_for_NGU = NULL; uint32_t gnb_port_for_NGU = 0; + char* gnb_interface_name_for_S1U = NULL; + char* gnb_ipv4_address_for_S1U = NULL; + uint32_t gnb_port_for_S1U = 0; char *address = NULL; char *cidr = NULL; char gtpupath[MAX_OPTNAME_SIZE*2 + 8]; - + uint8_t gnb_mode = 0; paramdef_t GNBSParams[] = GNBSPARAMS_DESC; - + paramdef_t NETParams[] = GNBNETPARAMS_DESC; paramdef_t GTPUParams[] = GNBGTPUPARAMS_DESC; LOG_I(GTPU,"Configuring GTPu\n"); @@ -692,25 +695,40 @@ int RCconfig_nr_gtpu(void ) { AssertFatal (num_gnbs >0, "Failed to parse config file no active gNodeBs in %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS); - sprintf(gtpupath,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - config_get( GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath); - + config_get(GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath); + config_get(NETParams,sizeof(NETParams)/sizeof(paramdef_t),gtpupath); + if (NETParams[0].strptr != NULL) { // SA + LOG_I(GTPU, "SA mode \n"); cidr = gnb_ipv4_address_for_NGU; + gnb_mode = 0; + } else {// NSA + LOG_I(GTPU, "NSA mode \n"); + cidr = gnb_ipv4_address_for_S1U; + gnb_mode = 1; + } + address = strtok(cidr, "/"); - + if (address) { MessageDef *message; AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, GTPV1U_ENB_S1_REQ))!=NULL,""); - // IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB NG_U !\n" ); + // IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); // LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up); - IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB NG_U !\n" ); - LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); - GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_NGU; + if (gnb_mode == 1) { // NSA + IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); + LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); + GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U; + } else {// TODO SA + IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" ); + LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); + GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_NGU; + } + itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) } else LOG_E(GTPU,"invalid address for NGU\n"); @@ -843,7 +861,7 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) { char snssaistr[MAX_OPTNAME_SIZE*2 + 8]; sprintf(snssaistr, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_PLMN_LIST, l); config_getlist(&SNSSAIParamList, SNSSAIParams, sizeof(SNSSAIParams)/sizeof(paramdef_t), snssaistr); - + NGAP_REGISTER_GNB_REQ (msg_p).mcc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; NGAP_REGISTER_GNB_REQ (msg_p).mnc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr; NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr; @@ -854,7 +872,6 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) { NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l]); NGAP_REGISTER_GNB_REQ (msg_p).num_nssai[l] = SNSSAIParamList.numelt; - for (int s = 0; s < SNSSAIParamList.numelt; ++s) { NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sST = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERIVE_TYPE_IDX].uptr; @@ -865,7 +882,7 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) { NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD[1] = (*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr & 0x00FF00) >> 8; NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD[2] = (*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr & 0x0000FF); } - } + } } sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k); config_getlist( &NGParamList,NGParams,sizeof(NGParams)/sizeof(paramdef_t),aprefix); diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 2172a346c7..b4ce7c325f 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -324,6 +324,12 @@ typedef struct ccparams_nr_x2 { #define GNB_PORT_FOR_X2C_IDX 6 /* S1 interface configuration parameters names */ +#define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1_MME "GNB_INTERFACE_NAME_FOR_S1_MME" +#define GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1_MME "GNB_IPV4_ADDRESS_FOR_S1_MME" +#define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U "GNB_INTERFACE_NAME_FOR_S1U" +#define GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1U "GNB_IPV4_ADDRESS_FOR_S1U" +#define GNB_CONFIG_STRING_GNB_PORT_FOR_S1U "GNB_PORT_FOR_S1U" + #define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF "GNB_INTERFACE_NAME_FOR_NG_AMF" #define GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF "GNB_IPV4_ADDRESS_FOR_NG_AMF" #define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU "GNB_INTERFACE_NAME_FOR_NGU" @@ -357,7 +363,10 @@ typedef struct ccparams_nr_x2 { #define GNBGTPUPARAMS_DESC { \ {GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU, NULL, 0, strptr:&gnb_interface_name_for_NGU, defstrval:"lo", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU, NULL, 0, strptr:&gnb_ipv4_address_for_NGU, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, uptr:&gnb_port_for_NGU, defintval:2152, TYPE_UINT, 0} \ +{GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, uptr:&gnb_port_for_NGU, defintval:2152, TYPE_UINT, 0}, \ +{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:&gnb_interface_name_for_S1U, defstrval:"lo", TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1U, NULL, 0, strptr:&gnb_ipv4_address_for_S1U, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:&gnb_port_for_S1U, defintval:2152, TYPE_UINT, 0} \ } /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 2de45db856..997fc6691e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -56,6 +56,8 @@ #include "flexran.pb-c.h" #include "flexran_agent_mac.h" #include +#include + #include "T.h" diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index f968f1b926..9a5946498d 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -49,6 +49,7 @@ uint16_t NCS_restricted_TypeB_delta_f_RA_5[14] = {36,57,60,63,65,68,71,77,81,8 uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69}; const char *prachfmt[]={"0","1","2","3", "A1","A2","A3","B1","B4","C0","C2","A1/B1","A2/B2","A3/B3"}; +const char *duplex_mode[]={"FDD","TDD"}; uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) { @@ -156,93 +157,93 @@ int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH) { // E.g. in row 20 and column 5 we have set value 66 ('0001000010') which means RACH can be sent at subframe 1 or 6 int64_t table_6_3_3_2_2_prachConfig_Index [256][9] = { //format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration -{0, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 -{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 -{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 -{0, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 -{0, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 -{0, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9 -{0, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8 -{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9 -{0, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{1, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 -{1, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 -{1, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 -{1, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 -{1, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 -{1, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3,6,9 -{2, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 4, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 2, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 2, 0, 32, 0, -1, -1, 0}, // (subframe number) 5 -{2, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 1, 0, 32, 0, -1, -1, 0}, // (subframe number) 5 -{3, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{3, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{3, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{3, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 -{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 -{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 -{3, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 -{3, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 -{3, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9 -{3, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8 -{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9 -{3, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0, -1, 16, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{0, -1, 16, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{0, -1, 16, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{0, -1, 16, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{0, -1, 8, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{0, -1, 8, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{0, -1, 8, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{0, -1, 8, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{0, -1, 4, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{0, -1, 4, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{0, -1, 4, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{0, -1, 4, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{0, -1, 2, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{0, -1, 2, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{0, -1, 2, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{0, -1, 2, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{0, -1, 1, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{0, -1, 1, 0, 16, 0, 1, 1, 0}, // (subframe number) 4 +{0, -1, 1, 0, 128, 0, 1, 1, 0}, // (subframe number) 7 +{0, -1, 1, 0, 66, 0, 1, 1, 0}, // (subframe number) 1,6 +{0, -1, 1, 0, 132, 0, 1, 1, 0}, // (subframe number) 2,7 +{0, -1, 1, 0, 264, 0, 1, 1, 0}, // (subframe number) 3,8 +{0, -1, 1, 0, 146, 0, 1, 1, 0}, // (subframe number) 1,4,7 +{0, -1, 1, 0, 292, 0, 1, 1, 0}, // (subframe number) 2,5,8 +{0, -1, 1, 0, 584, 0, 1, 1, 0}, // (subframe number) 3, 6, 9 +{0, -1, 1, 0, 341, 0, 1, 1, 0}, // (subframe number) 0,2,4,6,8 +{0, -1, 1, 0, 682, 0, 1, 1, 0}, // (subframe number) 1,3,5,7,9 +{0, -1, 1, 0, 1023, 0, 1, 1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{1, -1, 16, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{1, -1, 16, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{1, -1, 16, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{1, -1, 16, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{1, -1, 8, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{1, -1, 8, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{1, -1, 8, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{1, -1, 8, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{1, -1, 4, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{1, -1, 4, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{1, -1, 4, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{1, -1, 4, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{1, -1, 2, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{1, -1, 2, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{1, -1, 2, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{1, -1, 2, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{1, -1, 1, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{1, -1, 1, 0, 16, 0, 1, 1, 0}, // (subframe number) 4 +{1, -1, 1, 0, 128, 0, 1, 1, 0}, // (subframe number) 7 +{1, -1, 1, 0, 66, 0, 1, 1, 0}, // (subframe number) 1,6 +{1, -1, 1, 0, 132, 0, 1, 1, 0}, // (subframe number) 2,7 +{1, -1, 1, 0, 264, 0, 1, 1, 0}, // (subframe number) 3,8 +{1, -1, 1, 0, 146, 0, 1, 1, 0}, // (subframe number) 1,4,7 +{1, -1, 1, 0, 292, 0, 1, 1, 0}, // (subframe number) 2,5,8 +{1, -1, 1, 0, 584, 0, 1, 1, 0}, // (subframe number) 3,6,9 +{2, -1, 16, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{2, -1, 8, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{2, -1, 4, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{2, -1, 2, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{2, -1, 2, 0, 32, 0, 1, 1, 0}, // (subframe number) 5 +{2, -1, 1, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{2, -1, 1, 0, 32, 0, 1, 1, 0}, // (subframe number) 5 +{3, -1, 16, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{3, -1, 16, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{3, -1, 16, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{3, -1, 16, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{3, -1, 8, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{3, -1, 8, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{3, -1, 8, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{3, -1, 4, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{3, -1, 4, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{3, -1, 4, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{3, -1, 4, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{3, -1, 2, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{3, -1, 2, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{3, -1, 2, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{3, -1, 2, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{3, -1, 1, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{3, -1, 1, 0, 16, 0, 1, 1, 0}, // (subframe number) 4 +{3, -1, 1, 0, 128, 0, 1, 1, 0}, // (subframe number) 7 +{3, -1, 1, 0, 66, 0, 1, 1, 0}, // (subframe number) 1,6 +{3, -1, 1, 0, 132, 0, 1, 1, 0}, // (subframe number) 2,7 +{3, -1, 1, 0, 264, 0, 1, 1, 0}, // (subframe number) 3,8 +{3, -1, 1, 0, 146, 0, 1, 1, 0}, // (subframe number) 1,4,7 +{3, -1, 1, 0, 292, 0, 1, 1, 0}, // (subframe number) 2,5,8 +{3, -1, 1, 0, 584, 0, 1, 1, 0}, // (subframe number) 3, 6, 9 +{3, -1, 1, 0, 341, 0, 1, 1, 0}, // (subframe number) 0,2,4,6,8 +{3, -1, 1, 0, 682, 0, 1, 1, 0}, // (subframe number) 1,3,5,7,9 +{3, -1, 1, 0, 1023, 0, 1, 1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 {0xa1, -1, 16, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 {0xa1, -1, 16, 1, 16, 0, 2, 6, 2}, // (subframe number) 4 {0xa1, -1, 8, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 @@ -416,73 +417,73 @@ int64_t table_6_3_3_2_2_prachConfig_Index [256][9] = { // Table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum int64_t table_6_3_3_2_3_prachConfig_Index [256][9] = { //format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration -{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4) -{0, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8) -{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{0, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6) -{0, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5) -{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{0, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3) -{0, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2) -{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6) -{0, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6) -{0, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9) -{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8) -{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7) -{0, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9) -{0, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9) -{0, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9) -{0, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9) -{0, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9) -{0, -1, 1, 0, 960, 0, -1, -1, 0}, // (subrame number 6,7,8,9) -{0, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9) -{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9) -{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 2, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{2, -1, 16, 1, 64, 0, -1, -1, 0}, // (subrame number 6) -{2, -1, 8, 1, 64, 0, -1, -1, 0}, // (subrame number 6) -{2, -1, 4, 1, 64, 0, -1, -1, 0}, // (subrame number 6) -{2, -1, 2, 0, 64, 7, -1, -1, 0}, // (subrame number 6) -{2, -1, 2, 1, 64, 7, -1, -1, 0}, // (subrame number 6) -{2, -1, 1, 0, 64, 7, -1, -1, 0}, // (subrame number 6) -{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4) -{3, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8) -{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{3, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6) -{3, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5) -{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{3, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3) -{3, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2) -{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6) -{3, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6) -{3, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9) -{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8) -{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7) -{3, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9) -{3, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9) -{3, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9) -{3, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9) -{3, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9) -{3, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9) -{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9) +{0, -1, 16, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 8, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 4, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 2, 0, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 2, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 2, 0, 16, 0, 1, 1, 0}, // (subrame number 4) +{0, -1, 2, 1, 16, 0, 1, 1, 0}, // (subrame number 4) +{0, -1, 1, 0, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 1, 0, 256, 0, 1, 1, 0}, // (subrame number 8) +{0, -1, 1, 0, 128, 0, 1, 1, 0}, // (subrame number 7) +{0, -1, 1, 0, 64, 0, 1, 1, 0}, // (subrame number 6) +{0, -1, 1, 0, 32, 0, 1, 1, 0}, // (subrame number 5) +{0, -1, 1, 0, 16, 0, 1, 1, 0}, // (subrame number 4) +{0, -1, 1, 0, 8, 0, 1, 1, 0}, // (subrame number 3) +{0, -1, 1, 0, 4, 0, 1, 1, 0}, // (subrame number 2) +{0, -1, 1, 0, 66, 0, 1, 1, 0}, // (subrame number 1,6) +{0, -1, 1, 0, 66, 7, 1, 1, 0}, // (subrame number 1,6) +{0, -1, 1, 0, 528, 0, 1, 1, 0}, // (subrame number 4,9) +{0, -1, 1, 0, 264, 0, 1, 1, 0}, // (subrame number 3,8) +{0, -1, 1, 0, 132, 0, 1, 1, 0}, // (subrame number 2,7) +{0, -1, 1, 0, 768, 0, 1, 1, 0}, // (subrame number 8,9) +{0, -1, 1, 0, 784, 0, 1, 1, 0}, // (subrame number 4,8,9) +{0, -1, 1, 0, 536, 0, 1, 1, 0}, // (subrame number 3,4,9) +{0, -1, 1, 0, 896, 0, 1, 1, 0}, // (subrame number 7,8,9) +{0, -1, 1, 0, 792, 0, 1, 1, 0}, // (subrame number 3,4,8,9) +{0, -1, 1, 0, 960, 0, 1, 1, 0}, // (subrame number 6,7,8,9) +{0, -1, 1, 0, 594, 0, 1, 1, 0}, // (subrame number 1,4,6,9) +{0, -1, 1, 0, 682, 0, 1, 1, 0}, // (subrame number 1,3,5,7,9) +{1, -1, 16, 1, 128, 0, 1, 1, 0}, // (subrame number 7) +{1, -1, 8, 1, 128, 0, 1, 1, 0}, // (subrame number 7) +{1, -1, 4, 1, 128, 0, 1, 1, 0}, // (subrame number 7) +{1, -1, 2, 0, 128, 0, 1, 1, 0}, // (subrame number 7) +{1, -1, 2, 1, 128, 0, 1, 1, 0}, // (subrame number 7) +{1, -1, 1, 0, 128, 0, 1, 1, 0}, // (subrame number 7) +{2, -1, 16, 1, 64, 0, 1, 1, 0}, // (subrame number 6) +{2, -1, 8, 1, 64, 0, 1, 1, 0}, // (subrame number 6) +{2, -1, 4, 1, 64, 0, 1, 1, 0}, // (subrame number 6) +{2, -1, 2, 0, 64, 7, 1, 1, 0}, // (subrame number 6) +{2, -1, 2, 1, 64, 7, 1, 1, 0}, // (subrame number 6) +{2, -1, 1, 0, 64, 7, 1, 1, 0}, // (subrame number 6) +{3, -1, 16, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 8, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 4, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 2, 0, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 2, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 2, 0, 16, 0, 1, 1, 0}, // (subrame number 4) +{3, -1, 2, 1, 16, 0, 1, 1, 0}, // (subrame number 4) +{3, -1, 1, 0, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 1, 0, 256, 0, 1, 1, 0}, // (subrame number 8) +{3, -1, 1, 0, 128, 0, 1, 1, 0}, // (subrame number 7) +{3, -1, 1, 0, 64, 0, 1, 1, 0}, // (subrame number 6) +{3, -1, 1, 0, 32, 0, 1, 1, 0}, // (subrame number 5) +{3, -1, 1, 0, 16, 0, 1, 1, 0}, // (subrame number 4) +{3, -1, 1, 0, 8, 0, 1, 1, 0}, // (subrame number 3) +{3, -1, 1, 0, 4, 0, 1, 1, 0}, // (subrame number 2) +{3, -1, 1, 0, 66, 0, 1, 1, 0}, // (subrame number 1,6) +{3, -1, 1, 0, 66, 7, 1, 1, 0}, // (subrame number 1,6) +{3, -1, 1, 0, 528, 0, 1, 1, 0}, // (subrame number 4,9) +{3, -1, 1, 0, 264, 0, 1, 1, 0}, // (subrame number 3,8) +{3, -1, 1, 0, 132, 0, 1, 1, 0}, // (subrame number 2,7) +{3, -1, 1, 0, 768, 0, 1, 1, 0}, // (subrame number 8,9) +{3, -1, 1, 0, 784, 0, 1, 1, 0}, // (subrame number 4,8,9) +{3, -1, 1, 0, 536, 0, 1, 1, 0}, // (subrame number 3,4,9) +{3, -1, 1, 0, 896, 0, 1, 1, 0}, // (subrame number 7,8,9) +{3, -1, 1, 0, 792, 0, 1, 1, 0}, // (subrame number 3,4,8,9) +{3, -1, 1, 0, 594, 0, 1, 1, 0}, // (subrame number 1,4,6,9) +{3, -1, 1, 0, 682, 0, 1, 1, 0}, // (subrame number 1,3,5,7,9) {0xa1, -1, 16, 1, 512, 0, 2, 6, 2}, // (subrame number 9) {0xa1, -1, 8, 1, 512, 0, 2, 6, 2}, // (subrame number 9) {0xa1, -1, 4, 1, 512, 0, 1, 6, 2}, // (subrame number 9) @@ -947,6 +948,24 @@ int get_format0(uint8_t index, return format; } +int64_t *get_prach_config_info(uint32_t pointa, + uint8_t index, + uint8_t unpaired) { + int64_t *prach_config_info_p; + + if (pointa > 2016666) { //FR2 + prach_config_info_p = table_6_3_3_2_4_prachConfig_Index[index]; + } + else { // FR1 + if (unpaired) + prach_config_info_p = table_6_3_3_2_3_prachConfig_Index[index]; + else + prach_config_info_p = table_6_3_3_2_2_prachConfig_Index[index]; + } // FR2 / FR1 + + return prach_config_info_p; +} + void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss, uint16_t *slot_period, uint16_t *offset) { @@ -1400,7 +1419,7 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, else { r = L_ra/NCS; found_sequences = (nb_preambles/r) + (nb_preambles%r!=0); //ceil(nb_preambles/r) - printf(" found_sequences %u\n", found_sequences); + LOG_D(MAC, "Computing NR root sequences: found %u sequences\n", found_sequences); return (found_sequences); } } @@ -1438,12 +1457,17 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, AssertFatal(1==0,"Procedure to find nb of sequences for restricted type B not implemented yet"); } } - printf(" found_sequences %u\n", found_sequences); + LOG_D(MAC, "Computing NR root sequences: found %u sequences\n", found_sequences); return found_sequences; } } - +// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) +// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101) +// Notes: +// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL +// - Frequencies are expressed in KHz +// - col: NR_band ul_min ul_max dl_min dl_max step N_OFFs_DL deltaf_raster nr_bandentry_t nr_bandtable[] = { {1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100}, {2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100}, @@ -1451,18 +1475,28 @@ nr_bandentry_t nr_bandtable[] = { {5, 824000, 849000, 869000, 894000, 20, 173800, 100}, {7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100}, {8, 880000, 915000, 925000, 960000, 20, 185000, 100}, - {12, 698000, 716000, 728000, 746000, 20, 145800, 100}, + {12, 698000, 716000, 729000, 746000, 20, 145800, 100}, + {14, 788000, 798000, 758000, 768000, 20, 151600, 100}, + {18, 815000, 830000, 860000, 875000, 20, 172000, 100}, {20, 832000, 862000, 791000, 821000, 20, 158200, 100}, {25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100}, + {26, 814000, 849000, 859000, 894000, 20, 171800, 100}, {28, 703000, 758000, 758000, 813000, 20, 151600, 100}, + {29, 000, 000, 717000, 728000, 20, 143400, 100}, + {30, 2305000, 2315000, 2350000, 2360000, 20, 470000, 100}, {34, 2010000, 2025000, 2010000, 2025000, 20, 402000, 100}, {38, 2570000, 2620000, 2570000, 2630000, 20, 514000, 100}, {39, 1880000, 1920000, 1880000, 1920000, 20, 376000, 100}, {40, 2300000, 2400000, 2300000, 2400000, 20, 460000, 100}, {41, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, {41, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, + {47, 5855000, 5925000, 5855000, 5925000, 1, 790334, 15}, + //{48, 3550000, 3700000, 3550000, 3700000, 1, 636667, 15}, + //{48, 3550000, 3700000, 3550000, 3700000, 2, 636668, 30}, {50, 1432000, 1517000, 1432000, 1517000, 20, 286400, 100}, {51, 1427000, 1432000, 1427000, 1432000, 20, 285400, 100}, + {53, 2483500, 2495000, 2483500, 2495000, 20, 496700, 100}, + {65, 1920000, 2010000, 2110000, 2200000, 20, 422000, 100}, {66, 1710000, 1780000, 2110000, 2200000, 20, 422000, 100}, {70, 1695000, 1710000, 1995000, 2020000, 20, 399000, 100}, {71, 663000, 698000, 617000, 652000, 20, 123400, 100}, @@ -1473,22 +1507,31 @@ nr_bandentry_t nr_bandtable[] = { {77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30}, {78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15}, {78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30}, - {79, 4400000, 5000000, 4400000, 5000000, 1, 693334, 15}, - {79, 4400000, 5000000, 4400000, 5000000, 2, 693334, 30}, + {79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15}, + {79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30}, {80, 1710000, 1785000, 000, 000, 20, 342000, 100}, - {81, 860000, 915000, 000, 000, 20, 176000, 100}, + {81, 880000, 915000, 000, 000, 20, 176000, 100}, {82, 832000, 862000, 000, 000, 20, 166400, 100}, {83, 703000, 748000, 000, 000, 20, 140600, 100}, {84, 1920000, 1980000, 000, 000, 20, 384000, 100}, {86, 1710000, 1785000, 000, 000, 20, 342000, 100}, - {257,26500000,29500000,26500000,29500000, 1,2054166, 60}, - {257,26500000,29500000,26500000,29500000, 2,2054167, 120}, - {258,24250000,27500000,24250000,27500000, 1,2016667, 60}, - {258,24250000,27500000,24250000,27500000, 2,2016667, 120}, - {260,37000000,40000000,37000000,40000000, 1,2229166, 60}, - {260,37000000,40000000,37000000,40000000, 2,2229167, 120}, - {261,27500000,28350000,27500000,28350000, 1,2070833, 60}, - {261,27500000,28350000,27500000,28350000, 2,2070833, 120} + {89, 824000, 849000, 000, 000, 20, 342000, 100}, + {90, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, + {90, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, + {90, 2496000, 2690000, 2496000, 2690000, 20, 499200, 100}, + {91, 832000, 862000, 1427000, 1432000, 20, 285400, 100}, + {92, 832000, 862000, 1432000, 1517000, 20, 286400, 100}, + {93, 880000, 915000, 1427000, 1432000, 20, 285400, 100}, + {94, 880000, 915000, 1432000, 1517000, 20, 286400, 100}, + {95, 2010000, 2025000, 000, 000, 20, 402000, 100}, + {257,26500020,29500000,26500020,29500000, 1,2054166, 60}, + {257,26500080,29500000,26500080,29500000, 2,2054167, 120}, + {258,24250080,27500000,24250080,27500000, 1,2016667, 60}, + {258,24250080,27500000,24250080,27500000, 2,2016667, 120}, + {260,37000020,40000000,37000020,40000000, 1,2229166, 60}, + {260,37000080,40000000,37000080,40000000, 2,2229167, 120}, + {261,27500040,28350000,27500040,28350000, 1,2070833, 60}, + {261,27500040,28350000,27500040,28350000, 2,2070833, 120} }; @@ -1534,46 +1577,58 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = { #define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t)) -void get_band(uint64_t downlink_frequency, - uint16_t *current_band, - int32_t *current_offset, - lte_frame_type_t *current_type) -{ - int ind; - uint64_t center_frequency_khz; - uint64_t center_freq_diff_khz; - uint64_t dl_freq_khz = downlink_frequency/1000; +// Returns the corresponding row index of the NR table +int get_nr_table_idx(int nr_bandP, uint8_t scs_index){ - center_freq_diff_khz = 999999999999999999; // 2^64 - *current_band = 0; + int i, j; + int scs_khz = 15 << scs_index; + int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95}; + size_t s = sizeof(supplementary_bands)/sizeof(supplementary_bands[0]); - for ( ind=0; - ind < sizeof(nr_bandtable) / sizeof(nr_bandtable[0]); - ind++) { + for(j = 0; j < s; j++){ + if (nr_bandP == supplementary_bands[j]) + AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]); + } - LOG_I(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min,nr_bandtable[ind].ul_min); + AssertFatal(nr_bandP <= nr_bandtable[NR_BANDTABLE_SIZE-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[NR_BANDTABLE_SIZE-1].band); + for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); - if ( nr_bandtable[ind].dl_min <= dl_freq_khz && nr_bandtable[ind].dl_max >= dl_freq_khz ) { + // selection of correct Deltaf raster according to SCS + if ((nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) + i++; - center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min)/2; - if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){ - *current_band = nr_bandtable[ind].band; - *current_offset = (nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min)*1000; - center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz); + LOG_D(PHY, "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", i, nr_bandtable[i].band, nr_bandtable[i].dl_min,nr_bandtable[i].ul_min); - if (*current_offset == 0) - *current_type = TDD; - else - *current_type = FDD; - } - } - } + return i; - LOG_I( PHY, "DL frequency %"PRIu64": band %d, frame_type %d, UL frequency %"PRIu64"\n", - downlink_frequency, *current_band, *current_type, downlink_frequency+*current_offset); +} + +// Computes the duplex spacing (either positive or negative) in KHz +void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex){ + + int nr_table_idx = get_nr_table_idx(nr_bandP, scs_index); + + *delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min); + + LOG_D(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", *delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band); + +} + +void get_frame_type(uint16_t current_band, + uint8_t scs_index, + lte_frame_type_t *current_type){ + + int32_t current_offset; + get_delta_duplex(current_band, scs_index, ¤t_offset); + + current_offset *= 1000; + if (current_offset == 0) + *current_type = TDD; + else + *current_type = FDD; + + LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[*current_type], current_offset); - AssertFatal(*current_band != 0, - "Can't find EUTRA band for frequency %lu\n", downlink_frequency); } uint16_t config_bandwidth(int mu, int nb_rb, int nr_band) @@ -1689,6 +1744,15 @@ uint16_t config_bandwidth(int mu, int nb_rb, int nr_band) } +void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs){ + + uint32_t delta_arfcn = nrarfcn - N_OFFs; + + if(delta_arfcn%(nr_bandtable[i].step_size)!=0) + AssertFatal(1 == 0, "nrarfcn %u is not on the channel raster for step size %lu", nrarfcn, nr_bandtable[i].step_size); + +} + uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, @@ -1696,17 +1760,10 @@ uint32_t to_nrarfcn(int nr_bandP, { uint64_t dl_CarrierFreq_by_1k = dl_CarrierFreq / 1000; int bw_kHz = bw / 1000; - int scs_khz = 15< 260\n", nr_bandP); - for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); - - // selection of correct Deltaf raster according to SCS - if ( (nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) - i++; AssertFatal(dl_CarrierFreq_by_1k >= nr_bandtable[i].dl_min, "Band %d, bw %u : DL carrier frequency %llu kHz < %llu\n", @@ -1718,72 +1775,90 @@ uint32_t to_nrarfcn(int nr_bandP, (long long unsigned int)(nr_bandtable[i].dl_max - bw_kHz)); int deltaFglobal = 60; + uint32_t N_REF_Offs = 2016667; + uint64_t F_REF_Offs_khz = 24250080; - if (dl_CarrierFreq < 3e9) deltaFglobal = 15; - if (dl_CarrierFreq < 24.25e9) deltaFglobal = 5; + if (dl_CarrierFreq < 24.25e9) { + deltaFglobal = 15; + N_REF_Offs = 600000; + F_REF_Offs_khz = 3000000; + } + if (dl_CarrierFreq < 3e9) { + deltaFglobal = 5; + N_REF_Offs = 0; + F_REF_Offs_khz = 0; + } // This is equation before Table 5.4.2.1-1 in 38101-1-f30 // F_REF=F_REF_Offs + deltaF_Global(N_REF-NREF_REF_Offs) - nrarfcn = (((dl_CarrierFreq_by_1k - nr_bandtable[i].dl_min)/deltaFglobal)+nr_bandtable[i].N_OFFs_DL); - - delta_arfcn = nrarfcn - nr_bandtable[i].N_OFFs_DL; - if(delta_arfcn%(nr_bandtable[i].step_size)!=0) - AssertFatal(1==0,"dl_CarrierFreq %lu corresponds to %u which is not on the raster for step size %lu", - dl_CarrierFreq,nrarfcn,nr_bandtable[i].step_size); + nrarfcn = (((dl_CarrierFreq_by_1k - F_REF_Offs_khz)/deltaFglobal)+N_REF_Offs); + get_delta_arfcn(i, nrarfcn, nr_bandtable[i].N_OFFs_DL); return nrarfcn; } - +// This function computes the RF reference frequency from the NR-ARFCN according to 5.4.2.1 of 3GPP TS 38.104 +// this function applies to both DL and UL uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, - uint32_t dl_nrarfcn) + uint32_t nrarfcn) { - int i; int deltaFglobal = 5; - int scs_khz = 15< 599999 && dl_nrarfcn < 2016667) - deltaFglobal = 15; - if (dl_nrarfcn > 2016666 && dl_nrarfcn < 3279166) + if (nrarfcn > 599999 && nrarfcn < 2016667) { + deltaFglobal = 15; + N_REF_Offs = 600000; + F_REF_Offs_khz = 3000000; + } + if (nrarfcn > 2016666 && nrarfcn < 3279166) { deltaFglobal = 60; - - AssertFatal(nr_bandP <= 261, "nr_band %d > 260\n", nr_bandP); - for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); - AssertFatal(dl_nrarfcn>=nr_bandtable[i].N_OFFs_DL,"dl_nrarfcn %u < N_OFFs_DL[%d] %llu\n",dl_nrarfcn, nr_bandtable[i].band,(long long unsigned int)nr_bandtable[i].N_OFFs_DL); - - // selection of correct Deltaf raster according to SCS - if ( (nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) - i++; + N_REF_Offs = 2016667; + F_REF_Offs_khz = 24250080; + } - delta_arfcn = dl_nrarfcn - nr_bandtable[i].N_OFFs_DL; - if(delta_arfcn%(nr_bandtable[i].step_size)!=0) - AssertFatal(1==0,"dl_nrarfcn %u is not on the raster for step size %lu",dl_nrarfcn,nr_bandtable[i].step_size); + get_delta_duplex(nr_bandP, scs_index, &delta_duplex); - LOG_I(PHY,"Computing dl_frequency (pointA %llu => %llu (dlmin %llu, nr_bandtable[%d].N_OFFs_DL %llu))\n", - (unsigned long long)dl_nrarfcn, - (unsigned long long)(1000*(nr_bandtable[i].dl_min + (dl_nrarfcn - nr_bandtable[i].N_OFFs_DL) * deltaFglobal)), - (unsigned long long)nr_bandtable[i].dl_min, - i, - (unsigned long long)nr_bandtable[i].N_OFFs_DL); + if (delta_duplex <= 0){ // DL band >= UL band + if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL + N_OFFs = nr_bandtable[i].N_OFFs_DL; + freq_min = nr_bandtable[i].dl_min; + } else {// is FDD UL + N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal; + freq_min = nr_bandtable[i].ul_min; + } + } else { // UL band > DL band + if (nrarfcn >= nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal){ // is FDD UL + N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal; + freq_min = nr_bandtable[i].ul_min; + } else { // is FDD DL + N_OFFs = nr_bandtable[i].N_OFFs_DL; + freq_min = nr_bandtable[i].dl_min; + } + } + + LOG_D(MAC, "Frequency from NR-ARFCN for N_OFFs %lu, duplex spacing %d KHz, deltaFglobal %d KHz\n", N_OFFs, delta_duplex, deltaFglobal); + + AssertFatal(nrarfcn >= N_OFFs,"nrarfcn %u < N_OFFs[%d] %llu\n", nrarfcn, nr_bandtable[i].band, (long long unsigned int)N_OFFs); + get_delta_arfcn(i, nrarfcn, N_OFFs); + + frequency = 1000*(F_REF_Offs_khz + (nrarfcn - N_REF_Offs) * deltaFglobal); + + LOG_I(MAC, "Computing frequency (pointA %llu => %llu KHz (freq_min %llu KHz, NR band %d N_OFFs %llu))\n", + (unsigned long long)nrarfcn, + (unsigned long long)frequency/1000, + (unsigned long long)freq_min, + nr_bandP, + (unsigned long long)N_OFFs); + + return frequency; - return 1000*(nr_bandtable[i].dl_min + (dl_nrarfcn - nr_bandtable[i].N_OFFs_DL) * deltaFglobal); } - -int32_t get_nr_uldl_offset(int nr_bandP) -{ - int i; - - for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); - - AssertFatal(i < NR_BANDTABLE_SIZE, "i %d >= BANDTABLE_SIZE %ld\n", i, NR_BANDTABLE_SIZE); - - return (nr_bandtable[i].dl_min - nr_bandtable[i].ul_min); -} - - void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, int x_overhead, uint8_t numdmrscdmgroupnodata, @@ -1864,7 +1939,7 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) { case 0: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51311[Imcs][0]); break; @@ -1872,7 +1947,7 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) { case 1: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_51312[Imcs][0]); break; @@ -1880,13 +1955,14 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) { case 2: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51313[Imcs][0]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx); + LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx); + return 0; } } @@ -1895,7 +1971,7 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) { case 0: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51311[Imcs][1]); break; @@ -1903,7 +1979,7 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) { case 1: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_51312[Imcs][1]); break; @@ -1911,13 +1987,14 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) { case 2: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51313[Imcs][1]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx); + LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx); + return 0; } } @@ -1926,7 +2003,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { case 0: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51311[Imcs][0]); break; @@ -1934,7 +2011,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { case 1: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_51312[Imcs][0]); break; @@ -1942,7 +2019,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { case 2: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51313[Imcs][0]); break; @@ -1950,7 +2027,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { case 3: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_61411[Imcs][0]); break; @@ -1958,13 +2035,14 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { case 4: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_61412[Imcs][0]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx); + LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx); + return 0; } } @@ -1973,7 +2051,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { case 0: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51311[Imcs][1]); break; @@ -1981,7 +2059,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { case 1: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_51312[Imcs][1]); break; @@ -1989,7 +2067,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { case 2: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51313[Imcs][1]); break; @@ -1997,7 +2075,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { case 3: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_61411[Imcs][1]); break; @@ -2005,13 +2083,14 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { case 4: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_61412[Imcs][1]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx); + LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx); + return 0; } } diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 0a5a8c110c..f31723a7d6 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -36,6 +36,36 @@ #include "NR_CellGroupConfig.h" #include "nr_mac.h" + +// =============================================== +// SSB to RO mapping public defines and structures +// =============================================== +#define MAX_SSB_PER_RO (16) // Maximum number of SSBs that can be mapped to a single RO +#define MAX_TDM (7) // Maximum nb of PRACH occasions TDMed in a slot +#define MAX_FDM (8) // Maximum nb of PRACH occasions FDMed in a slot + +// PRACH occasion details +typedef struct prach_occasion_info { + uint8_t start_symbol; // 0 - 13 (14 symbols in a slot) + uint8_t fdm; // 0-7 (possible values of msg1-FDM: 1, 2, 4 or 8) + uint8_t slot; // 0 - 159 (maximum number of slots in a 10ms frame - @ 240kHz) + uint8_t frame; // 0 - 15 (maximum number of frames in a 160ms association pattern) + uint8_t mapped_ssb_idx[MAX_SSB_PER_RO]; // List of mapped SSBs + uint8_t nb_mapped_ssb; + uint16_t format; // RO preamble format +} prach_occasion_info_t; + +// PRACH occasion slot details +// A PRACH occasion slot is a series of PRACH occasions in time (symbols) and frequency +typedef struct prach_occasion_slot { + prach_occasion_info_t prach_occasion[MAX_TDM][MAX_FDM]; // Starting symbol of each PRACH occasions in a slot + uint8_t nb_of_prach_occasion_in_time; + uint8_t nb_of_prach_occasion_in_freq; +} prach_occasion_slot_t; + +// ======================================== + + typedef enum { NR_DL_DCI_FORMAT_1_0 = 0, NR_DL_DCI_FORMAT_1_1, @@ -66,7 +96,9 @@ typedef enum { uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); -void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type); +void get_frame_type(uint16_t nr_bandP, uint8_t scs_index, lte_frame_type_t *current_type); + +void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex); uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); @@ -133,6 +165,10 @@ int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPreco int get_format0(uint8_t index, uint8_t unpaired); +int64_t *get_prach_config_info(uint32_t pointa, + uint8_t index, + uint8_t unpaired); + uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config); int get_num_dmrs(uint16_t dmrs_mask ); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index bc98e16d39..7f98af2453 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -147,13 +147,14 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; NR_ServingCellConfigCommon_t *scc = mac->scc; int i; + lte_frame_type_t frame_type; mac->phy_config.Mod_id = module_id; mac->phy_config.CC_id = cc_idP; // carrier config - LOG_I(MAC,"UE Config Common\n"); + LOG_I(MAC, "Entering UE Config Common\n"); cfg->carrier_config.dl_bandwidth = config_bandwidth(scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth, @@ -200,15 +201,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, } } - lte_frame_type_t frame_type; - uint16_t band; - int32_t offset; - - get_band((cfg->carrier_config.dl_frequency)*1000, - &band, - &offset, - &frame_type); - + get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type); // cell config @@ -243,8 +236,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, cfg->ssb_table.ssb_mask_list[0].ssb_mask = 0; cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; for (i=0; i<4; i++) { - cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n"); cfg->tdd_table.tdd_period = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530; } - LOG_I(MAC,"Setting TDD configuration period to %d\n",cfg->tdd_table.tdd_period); if(cfg->cell_config.frame_duplex_type == TDD){ + LOG_I(MAC,"Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period); int return_tdd = set_tdd_config_nr_ue(cfg, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots, @@ -433,6 +426,9 @@ int nr_rrc_mac_config_req_ue( LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); } + // Setup the SSB to Rach Occasions mapping according to the config + build_ssb_to_ro_map(mac->scc, mac->phy_config.config_req.cell_config.frame_duplex_type); + /* if(mac_cell_group_configP != NULL){ if(mac_cell_group_configP->drx_Config != NULL ){ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 97c99b6050..e97695e201 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -63,7 +63,11 @@ #include "NR_PhysicalCellGroupConfig.h" #include "NR_CellGroupConfig.h" #include "NR_ServingCellConfig.h" - +#include "NR_MeasConfig.h" +#include "fapi_nr_ue_interface.h" +#include "NR_IF_Module.h" +#include "PHY/defs_nr_common.h" +#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" #define NB_NR_UE_MAC_INST 1 /*!\brief Maximum number of logical channl group IDs */ @@ -158,6 +162,7 @@ typedef struct { NR_CellGroupConfig_t *scg; NR_RACH_ConfigDedicated_t *rach_ConfigDedicated; int servCellIndex; + NR_CSI_ReportConfig_t *csirc; //// MAC config NR_DRX_Config_t *drx_Config; NR_SchedulingRequestConfig_t *schedulingRequestConfig; @@ -247,7 +252,7 @@ typedef struct { uint8_t generate_nr_prach; //// FAPI-like interface message - fapi_nr_ul_config_request_t ul_config_request; + fapi_nr_ul_config_request_t *ul_config_request; fapi_nr_dl_config_request_t dl_config_request; /// Interface module instances diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 4126b19b0b..1c5ff728f2 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -96,7 +96,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in @param module_id_t mod_id module ID @param int cc_id CC ID @param frame_t frame frame number - @param int slot reference number */ + @param int slot reference number + @param UE_nr_rxtx_proc_t *proc pointer to process context */ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, fapi_nr_dl_config_request_t *dl_config, fapi_nr_ul_config_request_t *ul_config, @@ -104,7 +105,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, module_id_t mod_id, int cc_id, frame_t frame, - int slot); + int slot, + int thread_id); /* \brief Get SR payload (0,1) from UE MAC @param Mod_id Instance id of UE in machine @@ -119,8 +121,8 @@ uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe); -int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format); -int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index,fapi_nr_dci_indication_pdu_t *dci); +int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format); +int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci); uint32_t get_ssb_frame(uint32_t test); uint32_t get_ssb_slot(uint32_t ssb_index); @@ -211,9 +213,10 @@ and fills the PRACH PDU per each FD occasion. @param module_idP Index of UE instance @param frameP Frame index @param slotP Slot index +@param thread_id RX/TX Thread ID @returns void */ -void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); +void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, int thread_id); /* \brief This function schedules the Msg3 transmission @param @@ -264,29 +267,29 @@ andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 @param CC_id Component Carrier Index @param frame @param gNB_id gNB index -@param nr_tti_tx slot for PRACH transmission +@param nr_slot_tx slot for PRACH transmission @returns indication to generate PRACH to phy */ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, + fapi_nr_ul_config_prach_pdu *prach_pdu, module_id_t mod_id, int CC_id, UE_MODE_t UE_mode, frame_t frame, uint8_t gNB_id, - int nr_tti_tx); + int nr_slot_tx); /* \brief Function implementing the routine for the selection of Random Access resources (5.1.2 TS 38.321). @param module_idP Index of UE instance @param CC_id Component Carrier Index @param gNB_index gNB index -@param t_id @param rach_ConfigDedicated @returns void */ void nr_get_prach_resources(module_id_t mod_id, int CC_id, uint8_t gNB_id, - uint8_t t_id, uint8_t first_Msg3, NR_PRACH_RESOURCES_t *prach_resources, + fapi_nr_ul_config_prach_pdu *prach_pdu, NR_RACH_ConfigDedicated_t * rach_ConfigDedicated); void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id); @@ -305,5 +308,8 @@ void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, uint8_t *nb_dmrs_re_per_rb, uint16_t *number_dmrs_symbols); +void build_ssb_to_ro_map(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired); + + #endif /** @}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index bae8e0d3c0..20e73073b9 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -57,10 +57,21 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) if (IS_SOFTMODEM_NOS1){ if (rlc_module_init(0) != 0) { - LOG_I(RLC, "Problem at RLC initiation \n"); - } - pdcp_layer_init(); - nr_DRB_preconfiguration(); + LOG_I(RLC, "Problem at RLC initiation \n"); + } + pdcp_layer_init(); + nr_DRB_preconfiguration(); + } + + // Allocate memory for ul_config_request in the mac instance. This is now a pointer and will + // point to a list of structures (one for each UL slot) to store PUSCH scheduling parameters + // received from UL DCI. + if (nr_ue_mac_inst->scc) { + int num_slots_ul = nr_ue_mac_inst->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + if (nr_ue_mac_inst->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0) + num_slots_ul++; + LOG_D(MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul); + nr_ue_mac_inst->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t)); } } else LOG_I(MAC,"Running without RRC instance\n"); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 117e5d2970..34b6d801c5 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -75,9 +75,9 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac); void nr_get_prach_resources(module_id_t mod_id, int CC_id, uint8_t gNB_id, - uint8_t t_id, uint8_t first_Msg3, NR_PRACH_RESOURCES_t *prach_resources, + fapi_nr_ul_config_prach_pdu *prach_pdu, NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); @@ -87,8 +87,8 @@ void nr_get_prach_resources(module_id_t mod_id, // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo - int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA = 0, numberOfRA_Preambles, i, deltaPreamble_Msg3 = 0; - uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, prach_ConfigIndex, SFN_nbr, Msg3_size; + int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA = 0, numberOfRA_Preambles, deltaPreamble_Msg3 = 0; + uint8_t noGroupB = 0, s_id, t_id, f_id, ul_carrier_id, Msg3_size; AssertFatal(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; @@ -100,6 +100,7 @@ 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) @@ -129,12 +130,81 @@ void nr_get_prach_resources(module_id_t mod_id, // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; + // Determine the SSB to RACH mapping ratio + // ======================================= + NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB + uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB + long cb_preambles_per_ssb; // Nb of preambles per SSB + int total_preambles_per_ssb; + int starting_preamble_nb = 0; + uint8_t ssb_nb_in_ro; + + switch (ssb_perRACH_config){ + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 8; + cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 4; + cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 2; + cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 1; + cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 2; + cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 4; + cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 8; + cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 16; + cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen; + break; + default: + AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config); + break; + } + Msg3_size = mac->RA_Msg3_size; numberOfRA_Preambles = 64; if(nr_rach_ConfigCommon->totalNumberOfRA_Preambles != NULL) numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles); + // Compute the proper Preamble selection params according to the selected SSB and the ssb_perRACH_OccasionAndCB_PreamblesPerSSB configuration + if ((true == multiple_ssb_per_ro) && + (ssb_rach_ratio > 1)) { + total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio; + + ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro; + starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro; + } + else { + total_preambles_per_ssb = numberOfRA_Preambles; + starting_preamble_nb = 0; + } + if (!nr_rach_ConfigCommon->groupBconfigured) { noGroupB = 1; } else { @@ -220,29 +290,30 @@ void nr_get_prach_resources(module_id_t mod_id, if (first_Msg3 == 1) { if (noGroupB == 1) { // use Group A preamble - prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; + prach_resources->ra_PreambleIndex = starting_preamble_nb + ((taus()) % cb_preambles_per_ssb); mac->RA_usedGroupA = 1; } else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) { // Group B is configured and RA preamble Group A is used // - todo add condition on CCCH_sdu_size for initiation by CCCH - prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; + prach_resources->ra_PreambleIndex = starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA); mac->RA_usedGroupA = 1; } else { // Group B preamble is configured and used // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A // the remaining belong to RA Preambles Group B - prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); + prach_resources->ra_PreambleIndex = starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); mac->RA_usedGroupA = 0; } } else { // Msg3 is being retransmitted if (mac->RA_usedGroupA == 1 && noGroupB == 1) { - prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; + prach_resources->ra_PreambleIndex = starting_preamble_nb + ((taus()) % cb_preambles_per_ssb); } else if (mac->RA_usedGroupA == 1 && noGroupB == 0){ - prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; + prach_resources->ra_PreambleIndex = starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA); } else { - prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); + prach_resources->ra_PreambleIndex = starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); } } + LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex); } @@ -268,27 +339,16 @@ void nr_get_prach_resources(module_id_t mod_id, // 1) this does not apply to contention-free RA Preamble for beam failure recovery request // 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario) - prach_ConfigIndex = rach_ConfigGeneric->prach_ConfigurationIndex; - // ra_RNTI computation - // - todo: this is for TDD FR1 only // - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier // - f_id: index of the PRACH occasion in the frequency domain // - s_id is starting symbol of the PRACH occasion [0...14] // - t_id is the first slot of the PRACH occasion in a system frame [0...80] - ul_carrier_id = 0; // NUL - f_id = rach_ConfigGeneric->msg1_FrequencyStart; - SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4]; - s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5]; + f_id = prach_pdu->num_ra; + t_id = prach_pdu->prach_slot; + s_id = prach_pdu->prach_start_symbol; - // Pick the first slot of the PRACH occasion in a system frame - for (i = 0; i < 10; i++){ - if (((SFN_nbr & (1 << i)) >> i) == 1){ - t_id = 2*i; - break; - } - } prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id; mac->ra_rnti = prach_resources->ra_RNTI; @@ -335,12 +395,13 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint // - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, + fapi_nr_ul_config_prach_pdu *prach_pdu, module_id_t mod_id, int CC_id, UE_MODE_t UE_mode, frame_t frame, uint8_t gNB_id, - int nr_tti_tx){ + int nr_slot_tx){ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES]; @@ -363,7 +424,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n"); - if (UE_mode < PUSCH && prach_resources->init_msg1) { + if (prach_resources->init_msg1) { LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", mac->RA_active); @@ -428,9 +489,9 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } //mac->RA_tx_frame = frame; - //mac->RA_tx_subframe = nr_tti_tx; + //mac->RA_tx_slot = nr_slot_tx; //mac->RA_backoff_frame = frame; - //mac->RA_backoff_subframe = nr_tti_tx; + //mac->RA_backoff_slot = nr_slot_tx; if (size_sdu > 0) { @@ -449,7 +510,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, // Fill in preamble and PRACH resources if (mac->generate_nr_prach == 1) - nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, prach_resources, rach_ConfigDedicated); + nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_slot_tx, prach_resources, prach_pdu, rach_ConfigDedicated); offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer (uint8_t *) payload, // UL MAC pdu pointer @@ -483,7 +544,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, // - handle backoff and raResponseWindow params // LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n", - // mod_id, frame, nr_tti_tx, mac->RA_window_cnt, mac->RA_tx_frame, mac->RA_tx_subframe); + // mod_id, frame, nr_slot_tx, mac->RA_window_cnt, mac->RA_tx_frame, mac->RA_tx_subframe); if (mac->RA_BI_found){ prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * mac->RA_backoff_indicator; @@ -503,7 +564,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) { - LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR reception failed \n", mod_id, frame, nr_tti_tx); + LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_slot_tx %d: RAR reception failed \n", mod_id, frame, nr_slot_tx); mac->ra_state = RA_UE_IDLE; mac->RA_PREAMBLE_TRANSMISSION_COUNTER++; @@ -561,22 +622,22 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, // frame_diff = (sframe_t) frame - mac->RA_backoff_frame; // if (frame_diff < 0) frame_diff = -frame_diff; // mac->RA_backoff_frame = frame; - // mac->RA_backoff_subframe = nr_tti_tx; + // mac->RA_backoff_slot = nr_slot_tx; // } // compute RA window parameters // if (mac->RA_window_cnt > 0){ // frame_diff = (frame_t) frame - mac->RA_tx_frame; // if (frame_diff < 0) frame_diff = -frame_diff; - // mac->RA_window_cnt -= ((10 * frame_diff) + (nr_tti_tx - mac->RA_tx_subframe)); - // LOG_D(MAC, "[MAC][UE %d][RAPROC] Frame %d, subframe %d: RA Active, adjusted window cnt %d\n", mod_id, frame, nr_tti_tx, mac->RA_window_cnt); + // mac->RA_window_cnt -= ((10 * frame_diff) + (nr_slot_tx - mac->RA_tx_subframe)); + // LOG_D(MAC, "[MAC][UE %d][RAPROC] Frame %d, subframe %d: RA Active, adjusted window cnt %d\n", mod_id, frame, nr_slot_tx, mac->RA_window_cnt); // } // mac->RA_tx_frame = frame; - // mac->RA_tx_subframe = nr_tti_tx; + // mac->RA_tx_slot = nr_slot_tx; // Fill in preamble and PRACH resources if (mac->generate_nr_prach == 1) - nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated); + nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_slot_tx, prach_resources, prach_pdu, rach_ConfigDedicated); } else { @@ -585,12 +646,12 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, LOG_D(MAC, "[MAC][UE %d][RAPROC][%d.%d]: RAR not received yet (RA window count %d) \n", mod_id, frame, - nr_tti_tx, + nr_slot_tx, mac->RA_window_cnt); // Fill in preamble and PRACH resources if (mac->generate_nr_prach == 1) - nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated); + nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_slot_tx, prach_resources, prach_pdu, rach_ConfigDedicated); } } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index a7e9a92693..f3935d9269 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -64,6 +64,10 @@ /* utils */ #include "assertions.h" +/* Tools */ +#include "asn1_conversions.h" +#include "SIMULATION/TOOLS/sim.h" // for taus + #include "common/utils/LOG/log.h" #include "SIMULATION/TOOLS/sim.h" // for taus #include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" @@ -72,12 +76,73 @@ #include #include +// ================================================ +// SSB to RO mapping private defines and structures +// ================================================ + +#define MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PERIOD (16) // Maximum association period is 16 +#define MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD (16) // Max association pattern period is 160ms and minimum PRACH configuration period is 10ms +#define MAX_NB_ASSOCIATION_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD (16) // Max nb of association periods in an association pattern period of 160ms +#define MAX_NB_FRAME_IN_PRACH_CONF_PERIOD (16) // Max PRACH configuration period is 160ms and frame is 10ms +#define MAX_NB_SLOT_IN_FRAME (160) // Max number of slots in a frame (@ SCS 240kHz = 160) +#define MAX_NB_FRAME_IN_ASSOCIATION_PATTERN_PERIOD (16) // Maximum number of frames in the maximum association pattern period +#define MAX_NB_SSB (64) // Maximum number of possible SSB indexes +#define MAX_RO_PER_SSB (8) // Maximum number of consecutive ROs that can be mapped to an SSB according to the ssb_per_RACH config + +// Maximum number of ROs that can be mapped to an SSB in an association pattern +// This is to reserve enough elements in the SSBs list for each mapped ROs for a single SSB +// An arbitrary maximum number is chosen to be safe: maximum number of slots in an association pattern * maximum number of ROs in a slot +#define MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN (MAX_TDM*MAX_FDM*MAX_NB_SLOT_IN_FRAME*MAX_NB_FRAME_IN_ASSOCIATION_PATTERN_PERIOD) + +// The PRACH Config period is a series of selected slots in one or multiple frames +typedef struct prach_conf_period { + prach_occasion_slot_t prach_occasion_slot_map[MAX_NB_FRAME_IN_PRACH_CONF_PERIOD][MAX_NB_SLOT_IN_FRAME]; + uint16_t nb_of_prach_occasion; // Total number of PRACH occasions in the PRACH Config period + uint8_t nb_of_frame; // Size of the PRACH Config period in number of 10ms frames + uint8_t nb_of_slot; // Nb of slots in each frame +} prach_conf_period_t; + +// The association period is a series of PRACH Config periods +typedef struct prach_association_period { + prach_conf_period_t *prach_conf_period_list[MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PERIOD]; + uint8_t nb_of_prach_conf_period; // Nb of PRACH configuration periods within the association period + uint8_t nb_of_frame; // Total number of frames included in the association period +} prach_association_period_t; + +// The association pattern is a series of Association periods +typedef struct prach_association_pattern { + prach_association_period_t prach_association_period_list[MAX_NB_ASSOCIATION_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD]; + prach_conf_period_t prach_conf_period_list[MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD]; + uint8_t nb_of_assoc_period; // Nb of association periods within the association pattern + uint8_t nb_of_prach_conf_period_in_max_period; // Nb of PRACH configuration periods within the maximum association pattern period (according to the size of the configured PRACH + uint8_t nb_of_frame; // Total number of frames included in the association pattern period (after mapping the SSBs and determining the real association pattern length) +} prach_association_pattern_t; + +// SSB details +typedef struct ssb_info { + boolean_t transmitted; // True if the SSB index is transmitted according to the SSB positions map configuration + prach_occasion_info_t *mapped_ro[MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN]; // List of mapped RACH Occasions to this SSB index + uint16_t nb_mapped_ro; // Total number of mapped ROs to this SSB index +} ssb_info_t; + +// List of all the possible SSBs and their details +typedef struct ssb_list_info { + ssb_info_t tx_ssb[MAX_NB_SSB]; + uint8_t nb_tx_ssb; +} ssb_list_info_t; + +static prach_association_pattern_t prach_assoc_pattern; +static ssb_list_info_t ssb_list; + +// =============================================== +// =============================================== + //#define ENABLE_MAC_PAYLOAD_DEBUG 1 #define DEBUG_EXTRACT_DCI 1 extern int bwp_id; extern dci_pdu_rel15_t *def_dci_pdu_rel15; -extern const uint16_t nr_slots_per_frame[5]; +extern const uint8_t nr_slots_per_frame[5]; extern void mac_rlc_data_ind ( const module_id_t module_idP, @@ -92,6 +157,617 @@ extern void mac_rlc_data_ind ( num_tb_t num_tbP, crc_t *crcs_pP); +// Build the list of all the valid RACH occasions in the maximum association pattern period according to the PRACH config +static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) { + + int x,y; // PRACH Configuration Index table variables used to compute the valid frame numbers + int y2; // PRACH Configuration Index table additional variable used to compute the valid frame numbers + uint8_t slot_shift_for_map; + uint8_t map_shift; + boolean_t even_slot_invalid; + int64_t s_map; + uint8_t prach_conf_start_symbol; // Starting symbol of the PRACH occasions in the PRACH slot + uint8_t N_t_slot; // Number of PRACH occasions in a 14-symbols PRACH slot + uint8_t N_dur; // Duration of a PRACH occasion (nb of symbols) + uint8_t frame; // Maximum is NB_FRAMES_IN_MAX_ASSOCIATION_PATTERN_PERIOD + uint8_t slot; // Maximum is the number of slots in a frame @ SCS 240kHz + uint16_t format = 0xffff; + uint8_t format2 = 0xff; + int nb_fdm; + + uint8_t config_index, mu; + uint32_t pointa; + int msg1_FDM; + + uint8_t prach_conf_period_idx; + uint8_t nb_of_frames_per_prach_conf_period; + uint8_t prach_conf_period_frame_idx; + int64_t *prach_config_info_p; + + NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; + + config_index = rach_ConfigGeneric->prach_ConfigurationIndex; + + if (setup->msg1_SubcarrierSpacing) + mu = *setup->msg1_SubcarrierSpacing; + else + mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + pointa = frequencyInfoDL->absoluteFrequencyPointA; + msg1_FDM = rach_ConfigGeneric->msg1_FDM; + + switch (msg1_FDM){ + case 0: + case 1: + case 2: + case 3: + nb_fdm = 1 << msg1_FDM; + break; + default: + AssertFatal(1 == 0, "Unknown msg1_FDM from rach_ConfigGeneric %d\n", msg1_FDM); + } + + // Create the PRACH occasions map + // ============================== + // WIP: For now assume no rejected PRACH occasions because of conflict with SSB or TDD_UL_DL_ConfigurationCommon schedule + + // Identify the proper PRACH Configuration Index table according to the operating frequency + LOG_D(MAC,"Pointa %u, mu = %u, PRACH config index = %u, unpaired = %u\n", pointa, mu, config_index, unpaired); + + prach_config_info_p = get_prach_config_info(pointa, config_index, unpaired); + + if (pointa > 2016666) { //FR2 + + x = prach_config_info_p[2]; + y = prach_config_info_p[3]; + y2 = prach_config_info_p[4]; + + s_map = prach_config_info_p[5]; + + prach_conf_start_symbol = prach_config_info_p[6]; + N_t_slot = prach_config_info_p[8]; + N_dur = prach_config_info_p[9]; + if (prach_config_info_p[1] != -1) + format2 = (uint8_t) prach_config_info_p[1]; + format = ((uint8_t) prach_config_info_p[0]) | (format2<<8); + + slot_shift_for_map = mu-2; + if ( (mu == 3) && (prach_config_info_p[7] == 1) ) + even_slot_invalid = true; + else + even_slot_invalid = false; + } + else { // FR1 + x = prach_config_info_p[2]; + y = prach_config_info_p[3]; + y2 = y; + + s_map = prach_config_info_p[4]; + + prach_conf_start_symbol = prach_config_info_p[5]; + N_t_slot = prach_config_info_p[7]; + N_dur = prach_config_info_p[8]; + if (prach_config_info_p[1] != -1) + format2 = (uint8_t) prach_config_info_p[1]; + format = ((uint8_t) prach_config_info_p[0]) | (format2<<8); + + slot_shift_for_map = mu; + if ( (mu == 1) && (prach_config_info_p[6] <= 1) ) + // no prach in even slots @ 30kHz for 1 prach per subframe + even_slot_invalid = true; + else + even_slot_invalid = false; + } // FR2 / FR1 + + prach_assoc_pattern.nb_of_prach_conf_period_in_max_period = MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD / x; + nb_of_frames_per_prach_conf_period = x; + + LOG_D(MAC,"nb_of_prach_conf_period_in_max_period %d\n", prach_assoc_pattern.nb_of_prach_conf_period_in_max_period); + + // Fill in the PRACH occasions table for every slot in every frame in every PRACH configuration periods in the maximum association pattern period + // ---------------------------------------------------------------------------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------------------------------------------- + // For every PRACH configuration periods + // ------------------------------------- + for (prach_conf_period_idx=0; prach_conf_period_idx> slot_shift_for_map; // in PRACH configuration index table slots are numbered wrt 60kHz + if ( (s_map>>map_shift)&0x01 ) { + // Valid slot + + // Additionally, for 30kHz/120kHz, we must check for the n_RA_Slot param also + if ( even_slot_invalid && (slot%2 == 0) ) + continue; // no prach in even slots @ 30kHz/120kHz for 1 prach per 60khz slot/subframe + + // We're good: valid frame and valid slot + // Compute all the PRACH occasions in the slot + + uint8_t n_prach_occ_in_time; + uint8_t n_prach_occ_in_freq; + + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_time = N_t_slot; + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_freq = nb_fdm; + + for (n_prach_occ_in_time=0; n_prach_occ_in_timestart_symbol = start_symbol; + prach_occasion_p->fdm = n_prach_occ_in_freq; + prach_occasion_p->frame = frame; + prach_occasion_p->slot = slot; + prach_occasion_p->format = format; + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_prach_occasion++; + + LOG_D(MAC,"Adding a PRACH occasion: frame %u, slot-symbol %d-%d, occ_in_time-occ_in-freq %d-%d, nb ROs in conf period %d, for this slot: RO# in time %d, RO# in freq %d\n", + frame, slot, start_symbol, n_prach_occ_in_time, n_prach_occ_in_freq, prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_prach_occasion, + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_time, + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_freq); + } // For every freq in the slot + } // For every time occasions in the slot + } // Valid slot? + } // For every slots in a frame + } // Valid frame? + } // For every frames in a prach configuration period + } // For every prach configuration periods in the maximum association pattern period (160ms) +} + +// Build the list of all the valid/transmitted SSBs according to the config +static void build_ssb_list(NR_ServingCellConfigCommon_t *scc) { + + // Create the list of transmitted SSBs + // =================================== + BIT_STRING_t *ssb_bitmap; + uint64_t ssb_positionsInBurst; + uint8_t ssb_idx = 0; + + switch (scc->ssb_PositionsInBurst->present) { + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap: + ssb_bitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap; + + ssb_positionsInBurst = BIT_STRING_to_uint8(ssb_bitmap); + LOG_D(MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst); + + for (uint8_t bit_nb=3; bit_nb<=3; bit_nb--) { + // If SSB is transmitted + if ((ssb_positionsInBurst>>bit_nb) & 0x01) { + ssb_list.nb_tx_ssb++; + ssb_list.tx_ssb[ssb_idx].transmitted = true; + LOG_D(MAC,"SSB idx %d transmitted\n", ssb_idx); + } + ssb_idx++; + } + break; + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap: + ssb_bitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap; + + ssb_positionsInBurst = BIT_STRING_to_uint8(ssb_bitmap); + LOG_D(MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst); + + for (uint8_t bit_nb=7; bit_nb<=7; bit_nb--) { + // If SSB is transmitted + if ((ssb_positionsInBurst>>bit_nb) & 0x01) { + ssb_list.nb_tx_ssb++; + ssb_list.tx_ssb[ssb_idx].transmitted = true; + LOG_D(MAC,"SSB idx %d transmitted\n", ssb_idx); + } + ssb_idx++; + } + break; + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap: + ssb_bitmap = &scc->ssb_PositionsInBurst->choice.longBitmap; + + ssb_positionsInBurst = BIT_STRING_to_uint64(ssb_bitmap); + LOG_D(MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst); + + for (uint8_t bit_nb=63; bit_nb<=63; bit_nb--) { + // If SSB is transmitted + if ((ssb_positionsInBurst>>bit_nb) & 0x01) { + ssb_list.nb_tx_ssb++; + ssb_list.tx_ssb[ssb_idx].transmitted = true; + LOG_D(MAC,"SSB idx %d transmitted\n", ssb_idx); + } + ssb_idx++; + } + break; + default: + AssertFatal(false,"ssb_PositionsInBurst not present\n"); + break; + } +} + +// Map the transmitted SSBs to the ROs and create the association pattern according to the config +static void map_ssb_to_ro(NR_ServingCellConfigCommon_t *scc) { + + // Map SSBs to PRACH occasions + // =========================== + // WIP: Assumption: No PRACH occasion is rejected because of a conflict with SSBs or TDD_UL_DL_ConfigurationCommon schedule + NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + + boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB + uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB + uint16_t required_nb_of_prach_occasion; // Nb of RACH occasions required to map all the SSBs + uint8_t required_nb_of_prach_conf_period; // Nb of PRACH configuration periods required to map all the SSBs + + // Determine the SSB to RACH mapping ratio + // ======================================= + switch (ssb_perRACH_config){ + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 8; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 4; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 2; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 1; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 2; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 4; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 8; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 16; + break; + default: + AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config); + break; + } + LOG_D(MAC,"SSB rach ratio %d, Multiple SSB per RO %d\n", ssb_rach_ratio, multiple_ssb_per_ro); + + // Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period + // ============================================================================================================== + // WIP: Assumption for now is that all the PRACH configuration periods within a maximum association pattern period have the same number of PRACH occasions + // (No PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule) + // There is only one possible association period which can contain up to 16 PRACH configuration periods + LOG_D(MAC,"Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period\n"); + if (true == multiple_ssb_per_ro) { + required_nb_of_prach_occasion = ((ssb_list.nb_tx_ssb-1) + ssb_rach_ratio) / ssb_rach_ratio; + } + else { + required_nb_of_prach_occasion = ssb_list.nb_tx_ssb * ssb_rach_ratio; + } + + required_nb_of_prach_conf_period = ((required_nb_of_prach_occasion-1) + prach_assoc_pattern.prach_conf_period_list[0].nb_of_prach_occasion) / prach_assoc_pattern.prach_conf_period_list[0].nb_of_prach_occasion; + + if (required_nb_of_prach_conf_period == 1) { + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 1; + } + else if (required_nb_of_prach_conf_period == 2) { + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 2; + } + else if (required_nb_of_prach_conf_period <= 4) { + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 4; + } + else if (required_nb_of_prach_conf_period <= 8) { + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 8; + } + else if (required_nb_of_prach_conf_period <= 16) { + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 16; + } + else { + AssertFatal(1 == 0, "Invalid number of PRACH config periods within an association period %d\n", required_nb_of_prach_conf_period); + } + + prach_assoc_pattern.nb_of_assoc_period = 1; // WIP: only one possible association period + prach_assoc_pattern.prach_association_period_list[0].nb_of_frame = prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period * prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame; + prach_assoc_pattern.nb_of_frame = prach_assoc_pattern.prach_association_period_list[0].nb_of_frame; + + LOG_D(MAC,"Assoc period %d, Nb of frames in assoc period %d\n", + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period, + prach_assoc_pattern.prach_association_period_list[0].nb_of_frame); + + // Proceed to the SSB to RO mapping + // ================================ + uint8_t association_period_idx; // Association period index within the association pattern + uint8_t ssb_idx = 0; + uint8_t prach_configuration_period_idx; // PRACH Configuration period index within the association pattern + prach_conf_period_t *prach_conf_period_p; + + // Map all the association periods within the association pattern period + LOG_D(MAC,"Proceed to the SSB to RO mapping\n"); + for (association_period_idx=0; association_period_idxnb_of_frame; frame++) { + for (slot=0; slotnb_of_slot; slot++) { + for (ro_in_time=0; ro_in_timeprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_time; ro_in_time++) { + for (ro_in_freq=0; ro_in_freqprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq; ro_in_freq++) { + prach_occasion_info_t *ro_p = &prach_conf_period_p->prach_occasion_slot_map[frame][slot].prach_occasion[ro_in_time][ro_in_freq]; + + // Go through the list of transmitted SSBs and map the required amount of SSBs to this RO + // WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO + // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule + for (; ssb_idxmapped_ssb_idx[ro_p->nb_mapped_ssb] = ssb_idx; + ro_p->nb_mapped_ssb++; + ssb_list.tx_ssb[ssb_idx].mapped_ro[ssb_list.tx_ssb[ssb_idx].nb_mapped_ro] = ro_p; + ssb_list.tx_ssb[ssb_idx].nb_mapped_ro++; + AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,"Too many mapped ROs (%d) to a single SSB\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro); + + LOG_D(MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq); + LOG_D(MAC,"Nb mapped ROs for this ssb idx: in the association period only %u\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro); + + // If all the required SSBs are mapped to this RO, exit the loop of SSBs + if (ro_p->nb_mapped_ssb == ssb_rach_ratio) { + ssb_idx++; + break; + } + } // if ssb_idx is transmitted + } // for ssb_idx + + // Exit the loop of ROs if there is no more SSB to map + if (MAX_NB_SSB == ssb_idx) break; + } // for ro_in_freq + + // Exit the loop of ROs if there is no more SSB to map + if (MAX_NB_SSB == ssb_idx) break; + } // for ro_in_time + + // Exit the loop of slots if there is no more SSB to map + if (MAX_NB_SSB == ssb_idx) break; + } // for slot + + // Exit the loop frames if there is no more SSB to map + if (MAX_NB_SSB == ssb_idx) break; + } // for frame + + // Exit the loop of PRACH configurations if there is no more SSB to map + if (MAX_NB_SSB == ssb_idx) break; + } // for n_prach_conf + + // WIP: note that there is no re-mapping of the SSBs within the association period since there is no invalid ROs in the PRACH config periods that would create this situation + + } // if multiple_ssbs_per_ro + + else { + // -------------------- + // -------------------- + // Multiple ROs per SSB + // -------------------- + // -------------------- + + n_prach_conf = 0; + + // Go through the list of transmitted SSBs + for (ssb_idx=0; ssb_idxnb_of_frame; frame++) { + for (; slotnb_of_slot; slot++) { + for (; ro_in_timeprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_time; ro_in_time++) { + for (; ro_in_freqprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq; ro_in_freq++) { + prach_occasion_info_t *ro_p = &prach_conf_period_p->prach_occasion_slot_map[frame][slot].prach_occasion[ro_in_time][ro_in_freq]; + + ro_p->mapped_ssb_idx[0] = ssb_idx; + ro_p->nb_mapped_ssb = 1; + ssb_list.tx_ssb[ssb_idx].mapped_ro[ssb_list.tx_ssb[ssb_idx].nb_mapped_ro] = ro_p; + ssb_list.tx_ssb[ssb_idx].nb_mapped_ro++; + AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,"Too many mapped ROs (%d) to a single SSB\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro); + nb_mapped_ro_in_association_period++; + + LOG_D(MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq); + LOG_D(MAC,"Nb mapped ROs for this ssb idx: in the association period only %u / total %u\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro, nb_mapped_ro_in_association_period); + + // Exit the loop if this SSB has been mapped to all the required ROs + // WIP: Assuming that ssb_rach_ratio equals the maximum nb of times a given ssb_idx is mapped within an association period: + // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule + if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { + ro_in_freq++; + break; + } + } // for ro_in_freq + + // Exit the loop if this SSB has been mapped to all the required ROs + if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { + break; + } + else ro_in_freq = 0; // else go to the next time symbol in that slot and reset the freq index + } // for ro_in_time + + // Exit the loop if this SSB has been mapped to all the required ROs + if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { + break; + } + else ro_in_time = 0; // else go to the next slot in that PRACH config period and reset the symbol index + } // for slot + + // Exit the loop if this SSB has been mapped to all the required ROs + if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { + break; + } + else slot = 0; // else go to the next frame in that PRACH config period and reset the slot index + } // for frame + + // Exit the loop if this SSB has been mapped to all the required ROs + if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { + break; + } + else frame = 0; // else go to the next PRACH config period in that association period and reset the frame index + } // for n_prach_conf + + } // if ssb_idx is transmitted + } // for ssb_idx + } // else if multiple_ssbs_per_ro + + } // for association_period_index +} + +// Returns a RACH occasion if any matches the SSB idx, the frame and the slot +static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, + int frame, + int slot, + prach_occasion_info_t **prach_occasion_info_pp) { + + ssb_info_t *ssb_info_p; + prach_occasion_slot_t *prach_occasion_slot_p = NULL; + + *prach_occasion_info_pp = NULL; + + // Search for a matching RO slot in the SSB_to_RO map + // A valid RO slot will match: + // - ssb_idx mapped to one of the ROs in that RO slot + // - exact slot number + // - frame offset + ssb_info_p = &ssb_list.tx_ssb[ssb_idx]; + for (uint8_t n_mapped_ro=0; n_mapped_ronb_mapped_ro; n_mapped_ro++) { + if ((slot == ssb_info_p->mapped_ro[n_mapped_ro]->slot) && + (ssb_info_p->mapped_ro[n_mapped_ro]->frame == (frame % prach_assoc_pattern.nb_of_frame))) { + + uint8_t prach_config_period_nb = ssb_info_p->mapped_ro[n_mapped_ro]->frame / prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame; + uint8_t frame_nb_in_prach_config_period = ssb_info_p->mapped_ro[n_mapped_ro]->frame % prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame; + prach_occasion_slot_p = &prach_assoc_pattern.prach_conf_period_list[prach_config_period_nb].prach_occasion_slot_map[frame_nb_in_prach_config_period][slot]; + } + } + + // If there is a matching RO slot in the SSB_to_RO map + if (NULL != prach_occasion_slot_p) + { + // A random RO mapped to the SSB index should be selected in the slot + + // First count the number of times the SSB index is found in that RO + uint8_t nb_mapped_ssb = 0; + + for (int ro_in_time=0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) { + for (int ro_in_freq=0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) { + prach_occasion_info_t *prach_occasion_info_p = &prach_occasion_slot_p->prach_occasion[ro_in_time][ro_in_freq]; + + for (uint8_t ssb_nb=0; ssb_nbnb_mapped_ssb; ssb_nb++) { + if (prach_occasion_info_p->mapped_ssb_idx[ssb_nb] == ssb_idx) { + nb_mapped_ssb++; + } + } + } + } + + // Choose a random SSB nb + uint8_t random_ssb_nb = 0; + + random_ssb_nb = ((taus()) % nb_mapped_ssb); + + // Select the RO according to the chosen random SSB nb + nb_mapped_ssb=0; + for (int ro_in_time=0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) { + for (int ro_in_freq=0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) { + prach_occasion_info_t *prach_occasion_info_p = &prach_occasion_slot_p->prach_occasion[ro_in_time][ro_in_freq]; + + for (uint8_t ssb_nb=0; ssb_nbnb_mapped_ssb; ssb_nb++) { + if (prach_occasion_info_p->mapped_ssb_idx[ssb_nb] == ssb_idx) { + if (nb_mapped_ssb == random_ssb_nb) { + *prach_occasion_info_pp = prach_occasion_info_p; + return 1; + } + else { + nb_mapped_ssb++; + } + } + } + } + } + } + + return 0; +} + +// Build the SSB to RO mapping upon RRC configuration update +void build_ssb_to_ro_map(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired){ + + // Clear all the lists and maps + memset(&prach_assoc_pattern, 0, sizeof(prach_association_pattern_t)); + memset(&ssb_list, 0, sizeof(ssb_list_info_t)); + + // Build the list of all the valid RACH occasions in the maximum association pattern period according to the PRACH config + LOG_D(MAC,"Build RO list\n"); + build_ro_list(scc, unpaired); + + // Build the list of all the valid/transmitted SSBs according to the config + LOG_D(MAC,"Build SSB list\n"); + build_ssb_list(scc); + + // Map the transmitted SSBs to the ROs and create the association pattern according to the config + LOG_D(MAC,"Map SSB to RO\n"); + map_ssb_to_ro(scc); + LOG_D(MAC,"Map SSB to RO done\n"); +} + void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, fapi_nr_dl_config_request_t *dl_config, fapi_nr_ul_config_request_t *ul_config, @@ -99,7 +775,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, module_id_t mod_id, int cc_id, frame_t frame, - int slot){ + int slot, + int thread_id){ scheduled_response->dl_config = dl_config; scheduled_response->ul_config = ul_config; @@ -108,7 +785,7 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, scheduled_response->CC_id = cc_id; scheduled_response->frame = frame; scheduled_response->slot = slot; - + scheduled_response->thread_id = thread_id; } uint32_t get_ssb_slot(uint32_t ssb_index){ @@ -498,8 +1175,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id, SFN_C_TYPE sfn_c=SFN_C_IMPOSSIBLE; // only valid for mux=1 uint32_t n_c=UINT_MAX; uint32_t number_of_search_space_per_slot=UINT_MAX; - uint32_t first_symbol_index=UINT_MAX; - uint32_t search_space_duration; // element of search space +// uint32_t first_symbol_index=UINT_MAX; +// uint32_t search_space_duration; // element of search space // 38.213 table 10.1-1 /// MUX PATTERN 1 @@ -516,13 +1193,13 @@ int8_t nr_ue_decode_mib(module_id_t module_id, sfn_c = SFN_C_MOD_2_EQ_0; } - if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (ssb_index&1)){ - first_symbol_index = num_symbols; - }else{ - first_symbol_index = table_38213_13_11_c4[index_4lsb]; - } +// if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (ssb_index&1)){ +// first_symbol_index = num_symbols; +// }else{ +// first_symbol_index = table_38213_13_11_c4[index_4lsb]; +// } // 38.213 chapter 13: over two consecutive slots - search_space_duration = 2; +// search_space_duration = 2; } if(mac->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){ @@ -530,15 +1207,15 @@ int8_t nr_ue_decode_mib(module_id_t module_id, number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb]; big_m = table_38213_13_12_c3[index_4lsb]; - if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (ssb_index&1)){ - first_symbol_index = 7; - }else if((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (ssb_index&1)){ - first_symbol_index = num_symbols; - }else{ - first_symbol_index = 0; - } +// if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (ssb_index&1)){ +// first_symbol_index = 7; +// }else if((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (ssb_index&1)){ +// first_symbol_index = num_symbols; +// }else{ +// first_symbol_index = 0; +// } // 38.213 chapter 13: over two consecutive slots - search_space_duration = 2; + //search_space_duration = 2; } /// MUX PATTERN 2 @@ -550,21 +1227,21 @@ int8_t nr_ue_decode_mib(module_id_t module_id, // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot // sfn_c = SFN_C_EQ_SFN_SSB; n_c = get_ssb_slot(ssb_index); - switch(ssb_index & 0x3){ // ssb_index(i) mod 4 - case 0: - first_symbol_index = 0; - break; - case 1: - first_symbol_index = 1; - break; - case 2: - first_symbol_index = 6; - break; - case 3: - first_symbol_index = 7; - break; - default: break; - } +// switch(ssb_index & 0x3){ // ssb_index(i) mod 4 +// case 0: +// first_symbol_index = 0; +// break; +// case 1: +// first_symbol_index = 1; +// break; +// case 2: +// first_symbol_index = 6; +// break; +// case 3: +// first_symbol_index = 7; +// break; +// default: break; +// } }else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){ // 38.213 Table 13-14 @@ -574,36 +1251,36 @@ int8_t nr_ue_decode_mib(module_id_t module_id, n_c = get_ssb_slot(ssb_index); switch(ssb_index & 0x7){ // ssb_index(i) mod 8 case 0: - first_symbol_index = 0; +// first_symbol_index = 0; break; case 1: - first_symbol_index = 1; +// first_symbol_index = 1; break; case 2: - first_symbol_index = 2; +// first_symbol_index = 2; break; case 3: - first_symbol_index = 3; +// first_symbol_index = 3; break; case 4: - first_symbol_index = 12; +// first_symbol_index = 12; n_c = get_ssb_slot(ssb_index) - 1; break; case 5: - first_symbol_index = 13; +// first_symbol_index = 13; n_c = get_ssb_slot(ssb_index) - 1; break; case 6: - first_symbol_index = 0; +// first_symbol_index = 0; break; case 7: - first_symbol_index = 1; +// first_symbol_index = 1; break; default: break; } }else{ ; } // 38.213 chapter 13: over one slot - search_space_duration = 1; +// search_space_duration = 1; } /// MUX PATTERN 3 @@ -614,24 +1291,24 @@ int8_t nr_ue_decode_mib(module_id_t module_id, // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot // sfn_c = SFN_C_EQ_SFN_SSB; n_c = get_ssb_slot(ssb_index); - switch(ssb_index & 0x3){ // ssb_index(i) mod 4 - case 0: - first_symbol_index = 4; - break; - case 1: - first_symbol_index = 8; - break; - case 2: - first_symbol_index = 2; - break; - case 3: - first_symbol_index = 6; - break; - default: break; - } +// switch(ssb_index & 0x3){ // ssb_index(i) mod 4 +// case 0: +// first_symbol_index = 4; +// break; +// case 1: +// first_symbol_index = 8; +// break; +// case 2: +// first_symbol_index = 2; +// break; +// case 3: +// first_symbol_index = 6; +// break; +// default: break; +// } }else{ ; } // 38.213 chapter 13: over one slot - search_space_duration = 1; +// search_space_duration = 1; } AssertFatal(number_of_search_space_per_slot!=UINT_MAX,""); @@ -670,6 +1347,61 @@ uint32_t get_ssb_frame(uint32_t test){ return test; } +/* + * This function returns the slot offset K2 corresponding to a given time domain + * indication value from RRC configuration. + */ +long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { + long k2 = -1; + // Get K2 from RRC configuration + NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup; + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; + if (pusch_config->pusch_TimeDomainAllocationList) { + pusch_TimeDomainAllocationList = pusch_config->pusch_TimeDomainAllocationList->choice.setup; + } + else if (mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { + pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + } + if (pusch_TimeDomainAllocationList) { + if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) { + LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n", + time_domain_ind, pusch_TimeDomainAllocationList->list.count); + return -1; + } + k2 = *pusch_TimeDomainAllocationList->list.array[time_domain_ind]->k2; + } + + LOG_D(MAC, "get_k2(): k2 is %ld\n", k2); + return k2; +} + +/* + * This function returns the UL config corresponding to a given UL slot + * from MAC instance . + */ +fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) { + //Check if request to access ul_config is for a UL slot + if (is_nr_UL_slot(mac->scc, slot) == 0) { + LOG_W(MAC, "Slot %d is not a UL slot. get_ul_config_request() called for wrong slot!!!\n", slot); + return NULL; + } + + // Calculate the index of the UL slot in mac->ul_config_request list. This is + // based on the TDD pattern (slot configuration period) and number of UL+mixed + // slots in the period. TS 38.213 Sec 11.1 + int mu = mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + NR_TDD_UL_DL_Pattern_t *tdd_pattern = &mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1; + const int num_slots_per_tdd = nr_slots_per_frame[mu] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity); + const int num_slots_ul = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0); + int index = slot + num_slots_ul - num_slots_per_tdd; + LOG_D(MAC, "nr_ue_procedures: get_ul_config_request() slots per tdd %d, num_slots_ul %d, index %d\n", + num_slots_per_tdd, + num_slots_ul, + index); + + return &mac->ul_config_request[index]; +} + // Performs : // 1. TODO: Call RRC for link status return to PHY // 2. TODO: Perform SR/BSR procedures for scheduling feedback @@ -740,7 +1472,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in */ dl_config->number_pdus = dl_config->number_pdus + 1; - fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot); + fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); } @@ -754,7 +1486,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in dcireq.dl_config_req.number_pdus = 0; nr_ue_dcireq(&dcireq); //to be replaced with function pointer later - fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot); + fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ mac->if_module->scheduled_response(&scheduled_response); } @@ -775,7 +1507,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } } else if (ul_info) { - if (get_softmodem_params()->phy_test && ul_info->slot_tx == 8) { // ULSCH is handled only in phy-test mode (consistently with OAI gNB) + // ULSCH is handled only in phy-test mode (consistently with OAI gNB) + if (get_softmodem_params()->phy_test) { uint8_t nb_dmrs_re_per_rb; uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; @@ -794,168 +1527,141 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); uint8_t access_mode = SCHEDULED_ACCESS; - // program PUSCH with UL DCI parameters - nr_dcireq_t dcireq; - nr_scheduled_response_t scheduled_response; - fapi_nr_tx_request_t tx_req; - fapi_nr_tx_request_body_t tx_req_body; - fapi_nr_ul_config_request_t *ul_config = &dcireq.ul_config_req; - nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; + fapi_nr_ul_config_request_t *ul_config_req = get_ul_config_request(mac, slot_tx); - fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &mac->ul_config_request.ul_config_list[0]; + // Schedule ULSCH only if the current frame and slot match those in ul_config_req + // AND if a UL DCI has been received (as indicated by num_pdus). + if ((frame_tx == ul_config_req->sfn && slot_tx == ul_config_req->slot) && + ul_config_req->number_pdus > 0) { + + // program PUSCH with UL DCI parameters + nr_scheduled_response_t scheduled_response; + fapi_nr_tx_request_t tx_req; + nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; - uint16_t rnti = ulcfg_pdu->pusch_config_pdu.rnti; - uint32_t rb_size = ulcfg_pdu->pusch_config_pdu.rb_size; - uint32_t rb_start = ulcfg_pdu->pusch_config_pdu.rb_start; - uint8_t nr_of_symbols = ulcfg_pdu->pusch_config_pdu.nr_of_symbols; - uint8_t start_symbol_index = ulcfg_pdu->pusch_config_pdu.start_symbol_index; - uint8_t nrOfLayers = 1; - uint8_t mcs_index = ulcfg_pdu->pusch_config_pdu.mcs_index; - uint8_t mcs_table = ulcfg_pdu->pusch_config_pdu.mcs_table; - uint8_t harq_process_id = ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id; - uint8_t rv_index = ulcfg_pdu->pusch_config_pdu.pusch_data.rv_index; - uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1); - uint8_t dmrs_config_type = 0; - uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; - // These should come from RRC config!!! - uint8_t ptrs_mcs1 = 2; - uint8_t ptrs_mcs2 = 4; - uint8_t ptrs_mcs3 = 10; - uint16_t n_rb0 = 25; - uint16_t n_rb1 = 75; - uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table); - uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size); - uint16_t number_dmrs_symbols = 0; - uint16_t ul_dmrs_symb_pos = l_prime_mask << start_symbol_index; + for (int j = 0; j < ul_config_req->number_pdus; j++) { + fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config_req->ul_config_list[j]; -#ifdef DEBUG_DCI - LOG_I(MAC, " UL config params \n rnti: %x \n rb_size: %d \n", - rnti, rb_size); - LOG_I(MAC, "rb_start: %x \n nr_of_symbols: %d \n start_symbol_index: %d \n nrOfLayers: %d \n mcs_index: %d \n \ - mcs_table: %d \n harq_process_id: %d \n ndi: %d \n num_cb: %d \n rv_index: %d \n", - rb_start, nr_of_symbols, start_symbol_index, nrOfLayers, mcs_index, - mcs_table, harq_process_id, ndi, num_cb, rv_index); -#endif + if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { - // PTRS ports configuration - // TbD: ptrs_dmrs_port and ptrs_port_index are not initialised! - ptrs_ports_list.ptrs_re_offset = 0; + // These should come from RRC config!!! + uint8_t ptrs_mcs1 = 2; + uint8_t ptrs_mcs2 = 4; + uint8_t ptrs_mcs3 = 10; + uint16_t n_rb0 = 25; + uint16_t n_rb1 = 75; + uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, ulcfg_pdu->pusch_config_pdu.mcs_index, ulcfg_pdu->pusch_config_pdu.mcs_table); + uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, ulcfg_pdu->pusch_config_pdu.rb_size); + uint16_t l_prime_mask = get_l_prime(ulcfg_pdu->pusch_config_pdu.nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1); + uint16_t ul_dmrs_symb_pos = l_prime_mask << ulcfg_pdu->pusch_config_pdu.start_symbol_index; - // Num PRB Overhead from PUSCH-ServingCellConfig - if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL) - N_PRB_oh = 0; - else - N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead; + uint8_t dmrs_config_type = 0; + uint16_t number_dmrs_symbols = 0; - ul_config->slot = ul_info->slot_tx; - ul_config->number_pdus = 1; - ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; - ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti; - ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size; - ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start; - ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols; - ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index; - ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos; - ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type; - ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index; - ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table; - ul_config->ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index; - ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id; - ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; - ul_config->ul_config_list[0].pusch_config_pdu.target_code_rate = nr_get_code_rate_ul(mcs_index, mcs_table); - ul_config->ul_config_list[0].pusch_config_pdu.qam_mod_order = nr_get_Qm_ul(mcs_index, mcs_table); + // PTRS ports configuration + // TbD: ptrs_dmrs_port and ptrs_port_index are not initialised! + ptrs_ports_list.ptrs_re_offset = 0; - if (1 << ptrs_time_density >= nr_of_symbols) { - ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS - } + // Num PRB Overhead from PUSCH-ServingCellConfig + if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL) + N_PRB_oh = 0; + else + N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead; - get_num_re_dmrs(&ul_config->ul_config_list[0].pusch_config_pdu, - &nb_dmrs_re_per_rb, - &number_dmrs_symbols); + ulcfg_pdu->pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos; + ulcfg_pdu->pusch_config_pdu.dmrs_config_type = dmrs_config_type; + ulcfg_pdu->pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1; + ulcfg_pdu->pusch_config_pdu.nrOfLayers = 1; + ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator = 0; + ulcfg_pdu->pusch_config_pdu.pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + ulcfg_pdu->pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density; + ulcfg_pdu->pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density; + ulcfg_pdu->pusch_config_pdu.pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; + //ulcfg_pdu->pusch_config_pdu.target_code_rate = nr_get_code_rate_ul(ulcfg_pdu->pusch_config_pdu.mcs_index, ulcfg_pdu->pusch_config_pdu.mcs_table); + //ulcfg_pdu->pusch_config_pdu.qam_mod_order = nr_get_Qm_ul(ulcfg_pdu->pusch_config_pdu.mcs_index, ulcfg_pdu->pusch_config_pdu.mcs_table); - TBS = nr_compute_tbs(ul_config->ul_config_list[0].pusch_config_pdu.qam_mod_order, - ul_config->ul_config_list[0].pusch_config_pdu.target_code_rate, - rb_size, - nr_of_symbols, - nb_dmrs_re_per_rb*number_dmrs_symbols, - N_PRB_oh, - 0, - nrOfLayers); - TBS_bytes = TBS/8; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS_bytes; + if (1 << ulcfg_pdu->pusch_config_pdu.pusch_ptrs.ptrs_time_density >= ulcfg_pdu->pusch_config_pdu.nr_of_symbols) { + ulcfg_pdu->pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS + } - if (IS_SOFTMODEM_NOS1){ - // Getting IP traffic to be transmitted - data_existing = nr_ue_get_sdu(mod_id, - cc_id, - frame_tx, - slot_tx, - 0, - ulsch_input_buffer, - TBS_bytes, - &access_mode); - } + get_num_re_dmrs(&ulcfg_pdu->pusch_config_pdu, + &nb_dmrs_re_per_rb, + &number_dmrs_symbols); - //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity - if (!IS_SOFTMODEM_NOS1 || !data_existing) { - //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid - //and block this traffic from being forwarded to the upper layers at the gNB - LOG_D(PHY, "Random data to be tranmsitted: \n"); + TBS = nr_compute_tbs(ulcfg_pdu->pusch_config_pdu.qam_mod_order, + ulcfg_pdu->pusch_config_pdu.target_code_rate, + ulcfg_pdu->pusch_config_pdu.rb_size, + ulcfg_pdu->pusch_config_pdu.nr_of_symbols, + nb_dmrs_re_per_rb*number_dmrs_symbols, + N_PRB_oh, + 0, + ulcfg_pdu->pusch_config_pdu.nrOfLayers); + TBS_bytes = TBS/8; + ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size = TBS_bytes; - //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) - //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should - //have a valid LCID (nr_process_mac_pdu function) - ulsch_input_buffer[0] = 0x31; + if (IS_SOFTMODEM_NOS1){ + // Getting IP traffic to be transmitted + data_existing = nr_ue_get_sdu(mod_id, + cc_id, + frame_tx, + slot_tx, + 0, + ulsch_input_buffer, + TBS_bytes, + &access_mode); + } - for (i = 1; i < TBS_bytes; i++) { - ulsch_input_buffer[i] = (unsigned char) rand(); - //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity + if (!IS_SOFTMODEM_NOS1 || !data_existing) { + //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid + //and block this traffic from being forwarded to the upper layers at the gNB + LOG_D(PHY, "Random data to be tranmsitted: \n"); + + //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) + //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should + //have a valid LCID (nr_process_mac_pdu function) + ulsch_input_buffer[0] = 0x31; + + for (i = 1; i < TBS_bytes; i++) { + ulsch_input_buffer[i] = (unsigned char) rand(); + //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + } + } + + #ifdef DEBUG_MAC_PDU + + LOG_D(PHY, "Is data existing ?: %d \n", data_existing); + LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS_bytes); + for (i = 0; i < TBS_bytes; i++) { + printf("%02x", ulsch_input_buffer[i]); + } + printf("\n"); + + #endif + + // Config UL TX PDU + tx_req.slot = slot_tx; + tx_req.sfn = frame_tx; + // tx_req->tx_config // TbD + tx_req.number_of_pdus++; + tx_req.tx_request_body[j].pdu_length = TBS_bytes; + tx_req.tx_request_body[j].pdu_index = j; + tx_req.tx_request_body[j].pdu = ulsch_input_buffer; } } -#ifdef DEBUG_MAC_PDU - - LOG_D(PHY, "Is data existing ?: %d \n", data_existing); - LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS_bytes); - for (i = 0; i < TBS_bytes; i++) { - printf("%02x", ulsch_input_buffer[i]); + fill_scheduled_response(&scheduled_response, NULL, ul_config_req, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ + mac->if_module->scheduled_response(&scheduled_response); } - printf("\n"); -#endif + // TODO: expand + // Note: Contention resolution is currently not active + if (mac->RA_contention_resolution_timer_active == 1) + ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx); - dcireq.module_id = mod_id; - dcireq.gNB_index = gNB_index; - dcireq.cc_id = cc_id; - dcireq.frame = rx_frame; - dcireq.slot = rx_slot; - - // Config UL TX PDU - tx_req.slot = slot_tx; - tx_req.sfn = frame_tx; - // tx_req->tx_config // TbD - tx_req.number_of_pdus = 1; - tx_req_body.pdu_length = TBS_bytes; - tx_req_body.pdu_index = 0; - tx_req_body.pdu = ulsch_input_buffer; - tx_req.tx_request_body = &tx_req_body; - - fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ - mac->if_module->scheduled_response(&scheduled_response); } - // TODO: expand - // Note: Contention resolution is currently not active - if (mac->RA_contention_resolution_timer_active == 1) - ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx); - } else if (get_softmodem_params()->do_ra){ NR_UE_MAC_INST_t *mac = get_mac_inst(ul_info->module_id); @@ -965,8 +1671,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; nr_scheduled_response_t scheduled_response; fapi_nr_tx_request_t tx_req; - fapi_nr_tx_request_body_t tx_req_body; - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; + //fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx); + fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0]; fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus]; uint16_t TBS_bytes = ul_config_list->pusch_config_pdu.pusch_data.tb_size; @@ -1007,14 +1713,13 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in tx_req.slot = ul_info->slot_tx; tx_req.sfn = ul_info->frame_tx; tx_req.number_of_pdus = 1; - tx_req_body.pdu_length = TBS_bytes; - tx_req_body.pdu_index = 0; - tx_req_body.pdu = ulsch_input_buffer; - tx_req.tx_request_body = &tx_req_body; + tx_req.tx_request_body[0].pdu_length = TBS_bytes; + tx_req.tx_request_body[0].pdu_index = 0; + tx_req.tx_request_body[0].pdu = ulsch_input_buffer; ul_config_list->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; ul_config->number_pdus++; // scheduled_response - fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, ul_info->module_id, ul_info->cc_id, ul_info->frame_rx, ul_info->slot_rx); + fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, ul_info->module_id, ul_info->cc_id, ul_info->frame_rx, ul_info->slot_rx, ul_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ mac->if_module->scheduled_response(&scheduled_response); } @@ -1066,22 +1771,19 @@ void nr_ue_msg3_scheduler(NR_UE_MAC_INST_t *mac, } // This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x -// It fills the PRACH PDU per each FD occasion. // PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3. // - todo: // - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config -void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { +void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, int thread_id) { - uint8_t config_index, mu, N_dur, N_t_slot, start_symbol; - uint16_t RA_sfn_index; - uint8_t N_RA_slot; - uint8_t config_period; uint16_t format, format0, format1, ncs; - int msg1_FDM, is_nr_prach_slot, fdm; + int is_nr_prach_slot; + prach_occasion_info_t *prach_occasion_info_p; NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; + //fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP); + fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0]; fapi_nr_ul_config_prach_pdu *prach_config_pdu; fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; fapi_nr_prach_config_t *prach_config = &cfg->prach_config; @@ -1089,136 +1791,121 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s NR_ServingCellConfigCommon_t *scc = mac->scc; NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; - NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; - config_index = rach_ConfigGeneric->prach_ConfigurationIndex; mac->RA_offset = 2; // to compensate the rx frame offset at the gNB mac->generate_nr_prach = 0; // Reset flag for PRACH generation if (is_nr_UL_slot(scc, slotP)) { - if (setup->msg1_SubcarrierSpacing) - mu = *setup->msg1_SubcarrierSpacing; - else - mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + // WIP Need to get the proper selected ssb_idx + // Initial beam selection functionality is not available yet + uint8_t selected_gnb_ssb_idx = 0; - is_nr_prach_slot = get_nr_prach_info_from_index(config_index, - (int)frameP, - (int)slotP, - frequencyInfoDL->absoluteFrequencyPointA, - mu, - cfg->cell_config.frame_duplex_type, - &format, - &start_symbol, - &N_t_slot, - &N_dur, - &RA_sfn_index, - &N_RA_slot, - &config_period); + // Get any valid PRACH occasion in the current slot for the selected SSB index + is_nr_prach_slot = get_nr_prach_info_from_ssb_index(selected_gnb_ssb_idx, + (int)frameP, + (int)slotP, + &prach_occasion_info_p); if (is_nr_prach_slot && mac->ra_state == RA_UE_IDLE) { + AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n"); mac->generate_nr_prach = 1; - fdm = rach_ConfigGeneric->msg1_FDM; - - switch (fdm){ - case 0: - case 1: - case 2: - case 3: - msg1_FDM = 1 << fdm; - break; - default: - AssertFatal(1 == 0, "Unknown msg1_FDM from rach_ConfigGeneric %d\n", fdm); - } - + format = prach_occasion_info_p->format; format0 = format & 0xff; // single PRACH format format1 = (format >> 8) & 0xff; // dual PRACH format ul_config->sfn = frameP; ul_config->slot = slotP; - for (int n = 0; n < msg1_FDM; n++) { // one structure per frequency domain occasion + ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH; + prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; + memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); + ul_config->number_pdus += 1; - ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH; - prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; - memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); - ul_config->number_pdus += 1; + ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); - ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); + prach_config_pdu->phys_cell_id = *scc->physCellId; + prach_config_pdu->num_prach_ocas = 1; + prach_config_pdu->prach_slot = prach_occasion_info_p->slot; + prach_config_pdu->prach_start_symbol = prach_occasion_info_p->start_symbol; + prach_config_pdu->num_ra = prach_occasion_info_p->fdm; - // filling PRACH PDU for FAPI config request - prach_config_pdu->phys_cell_id = *scc->physCellId; - prach_config_pdu->num_prach_ocas = N_t_slot; - prach_config_pdu->prach_start_symbol = start_symbol; - prach_config_pdu->num_ra = n; - prach_config_pdu->num_cs = ncs; - prach_config_pdu->root_seq_id = prach_config->num_prach_fd_occasions_list[n].prach_root_sequence_index; - prach_config_pdu->restricted_set = prach_config->restricted_set_config; - prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[n].k1; + prach_config_pdu->num_cs = ncs; + prach_config_pdu->root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].prach_root_sequence_index; + prach_config_pdu->restricted_set = prach_config->restricted_set_config; + prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1; - if (format1 != 0xff) { - switch(format0) { // dual PRACH format - case 0xa1: - prach_config_pdu->prach_format = 11; - break; - case 0xa2: - prach_config_pdu->prach_format = 12; - break; - case 0xa3: - prach_config_pdu->prach_format = 13; - break; - default: - AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); - } - } else { - switch(format0) { // single PRACH format - case 0: - prach_config_pdu->prach_format = 0; - break; - case 1: - prach_config_pdu->prach_format = 1; - break; - case 2: - prach_config_pdu->prach_format = 2; - break; - case 3: - prach_config_pdu->prach_format = 3; - break; - case 0xa1: - prach_config_pdu->prach_format = 4; - break; - case 0xa2: - prach_config_pdu->prach_format = 5; - break; - case 0xa3: - prach_config_pdu->prach_format = 6; - break; - case 0xb1: - prach_config_pdu->prach_format = 7; - break; - case 0xb4: - prach_config_pdu->prach_format = 8; - break; - case 0xc0: - prach_config_pdu->prach_format = 9; - break; - case 0xc2: - prach_config_pdu->prach_format = 10; - break; - default: - AssertFatal(1 == 0, "Invalid PRACH format"); - } - } + LOG_D(MAC,"Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra); + + // Search which SSB is mapped in the RO (among all the SSBs mapped to this RO) + for (prach_config_pdu->ssb_nb_in_ro=0; prach_config_pdu->ssb_nb_in_ronb_mapped_ssb; prach_config_pdu->ssb_nb_in_ro++) { + if (prach_occasion_info_p->mapped_ssb_idx[prach_config_pdu->ssb_nb_in_ro] == selected_gnb_ssb_idx) + break; } - } + AssertFatal(prach_config_pdu->ssb_nb_in_ronb_mapped_ssb, "%u not found in the mapped SSBs to the PRACH occasion", selected_gnb_ssb_idx); - fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP); + if (format1 != 0xff) { + switch(format0) { // dual PRACH format + case 0xa1: + prach_config_pdu->prach_format = 11; + break; + case 0xa2: + prach_config_pdu->prach_format = 12; + break; + case 0xa3: + prach_config_pdu->prach_format = 13; + break; + default: + AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + } + } else { + switch(format0) { // single PRACH format + case 0: + prach_config_pdu->prach_format = 0; + break; + case 1: + prach_config_pdu->prach_format = 1; + break; + case 2: + prach_config_pdu->prach_format = 2; + break; + case 3: + prach_config_pdu->prach_format = 3; + break; + case 0xa1: + prach_config_pdu->prach_format = 4; + break; + case 0xa2: + prach_config_pdu->prach_format = 5; + break; + case 0xa3: + prach_config_pdu->prach_format = 6; + break; + case 0xb1: + prach_config_pdu->prach_format = 7; + break; + case 0xb4: + prach_config_pdu->prach_format = 8; + break; + case 0xc0: + prach_config_pdu->prach_format = 9; + break; + case 0xc2: + prach_config_pdu->prach_format = 10; + break; + default: + AssertFatal(1 == 0, "Invalid PRACH format"); + } + } // if format1 + } // is_nr_prach_slot + + fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) mac->if_module->scheduled_response(&scheduled_response); - } + } // if is_nr_UL_slot } //////////////////////////////////////////////////////////////////////////// @@ -1281,7 +1968,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, csi_MeasConfig_t csi_MeasConfig = ue->csi_MeasConfig; PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig= ue->PUSCH_ServingCellConfig; PDSCH_ServingCellConfig_t PDSCH_ServingCellConfig= ue->PDSCH_ServingCellConfig; - NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]; + NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[proc->thread_id][eNB_id]; // 1 CARRIER_IN // crossCarrierSchedulingConfig from higher layers, variable crossCarrierSchedulingConfig indicates if 'cross carrier scheduling' is enabled or not: // if No cross carrier scheduling: number of bits for CARRIER_IND is 0 @@ -2233,7 +2920,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind ){ int dmrs_typeA_pos = mac->scc->dmrs_TypeA_Position; - uint8_t k_offset=0; +// uint8_t k_offset=0; uint8_t sliv_S=0; uint8_t sliv_L=0; uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 @@ -2374,7 +3061,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, dlsch_config_pdu->number_symbols=L; } else {// Default configuration from tables - k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; +// k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1]; sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2]; // k_offset = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; @@ -2417,7 +3104,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, pusch_config_pdu->nr_of_symbols=L; } else { - k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; +// k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1]; sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2]; // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; @@ -2430,7 +3117,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, return 0; } ////////////// -int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index,fapi_nr_dci_indication_pdu_t *dci) { +int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); @@ -2438,16 +3125,19 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits); int dci_format = nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,def_dci_pdu_rel15); - return (nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci_format)); + return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci->rnti, dci_format)); } -int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){ +int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){ int bwp_id = 1; + int mu = 0; + long k2 = 0; + uint16_t frame_tx = 0, slot_tx = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; + fapi_nr_ul_config_request_t *ul_config = NULL; //const uint16_t n_RB_DLBWP = dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP; //make sure this has been set AssertFatal(mac->DLbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n"); @@ -2477,6 +3167,28 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space * 50 SUL_IND_0_0: */ + // Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, + // where K2 is the offset between the slot in which UL DCI is received and the slot + // in which ULSCH should be scheduled. K2 is configured in RRC configuration. + + // Get the numerology to calculate the Tx frame and slot + mu = mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + // Get slot offset K2 which will be used to calculate TX slot + k2 = get_k2(mac, dci->time_domain_assignment.val); + if (k2 < 0) // This can happen when a false DCI is received + return -1; + // Calculate TX slot and frame + slot_tx = (slot + k2) % nr_slots_per_frame[mu]; + frame_tx = ((slot + k2) > nr_slots_per_frame[mu]) ? (frame + 1) % 1024 : frame; + + // Get UL config request corresponding slot_tx + ul_config = get_ul_config_request(mac, slot_tx); + //AssertFatal(ul_config != NULL, "nr_ue_process_dci(): ul_config is NULL\n"); + if (!ul_config) { + LOG_W(MAC, "nr_ue_process_dci(): ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n",frame,slot); + return -1; + } + ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rnti = rnti; nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu_0_0 = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; @@ -2515,7 +3227,10 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc } /* SUL_IND_0_0 */ // To be implemented, FIXME!!! + ul_config->slot = slot_tx; + ul_config->sfn = frame_tx; ul_config->number_pdus = ul_config->number_pdus + 1; + LOG_D(MAC, "nr_ue_process_dci(): Calculated frame and slot for pusch Tx: %d.%d, number of pdus %d\n", ul_config->sfn, ul_config->slot, ul_config->number_pdus); break; case NR_UL_DCI_FORMAT_0_1: @@ -2547,6 +3262,28 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc * 48 UL_SCH_IND * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space */ + // Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, + // where K2 is the offset between the slot in which UL DCI is received and the slot + // in which ULSCH should be scheduled. K2 is configured in RRC configuration. + + // Get the numerology to calculate the Tx frame and slot + mu = mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + // Get slot offset K2 which will be used to calculate TX slot + k2 = get_k2(mac, dci->time_domain_assignment.val); + if (k2 < 0) // This can happen when a false DCI is received + return -1; + // Calculate TX slot and frame + slot_tx = (slot + k2) % nr_slots_per_frame[mu]; + frame_tx = ((slot + k2) > nr_slots_per_frame[mu]) ? (frame + 1) % 1024 : frame; + + // Get UL config request corresponding slot_tx + ul_config = get_ul_config_request(mac, slot_tx); + //AssertFatal(ul_config != NULL, "nr_ue_process_dci(): ul_config is NULL\n"); + if (!ul_config) { + LOG_W(MAC, "nr_ue_process_dci(): ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n",frame,slot); + return -1; + } + ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rnti = rnti; nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu_0_1 = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; @@ -2583,6 +3320,13 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc pusch_config_pdu_0_1->mcs_table = get_pusch_mcs_table(pusch_config->mcs_TableTransformPrecoder, 1, dci_format, NR_RNTI_C, NR_SearchSpace__searchSpaceType_PR_ue_Specific, false); + pusch_config_pdu_0_1->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu_0_1->mcs_index, pusch_config_pdu_0_1->mcs_table); + pusch_config_pdu_0_1->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu_0_1->mcs_index, pusch_config_pdu_0_1->mcs_table); + if (pusch_config_pdu_0_1->target_code_rate == 0 || pusch_config_pdu_0_1->qam_mod_order == 0) { + LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected UL DCI. Ignoring DCI! \n"); + return -1; + } + /* NDI */ pusch_config_pdu_0_1->pusch_data.new_data_indicator = dci->ndi; /* RV */ @@ -2840,8 +3584,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc /* UL_SCH_IND */ // A value of "1" indicates UL-SCH shall be transmitted on the PUSCH and // a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH - + + ul_config->slot = slot_tx; + ul_config->sfn = frame_tx; ul_config->number_pdus = ul_config->number_pdus + 1; + LOG_D(MAC, "nr_ue_process_dci(): Calculated frame and slot for pusch Tx: %d.%d, number of pdus %d\n", ul_config->sfn, ul_config->slot, ul_config->number_pdus); break; case NR_DL_DCI_FORMAT_1_0: @@ -3243,7 +3990,6 @@ void nr_ue_send_sdu(module_id_t module_idP, #endif */ - /* #if defined(ENABLE_MAC_PAYLOAD_DEBUG) LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); for (i = 0; i < 32; i++) { @@ -3251,7 +3997,6 @@ void nr_ue_send_sdu(module_id_t module_idP, } LOG_T(MAC, "\n"); #endif - */ // Processing MAC PDU // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs @@ -3905,6 +4650,7 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); //#endif + LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len); switch(rx_lcid){ // MAC CE diff --git a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c index 06db41df9c..3fbd5a16b0 100644 --- a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c +++ b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c @@ -77,7 +77,7 @@ void nr_config_Msg3_pdu(NR_UE_MAC_INST_t *mac, uint8_t nb_dmrs_re_per_rb; uint16_t number_dmrs_symbols = 0; int N_PRB_oh; - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; + fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0]; nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; NR_ServingCellConfigCommon_t *scc = mac->scc; NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; @@ -274,15 +274,22 @@ uint16_t nr_ue_process_rar(module_id_t mod_id, if (ue_mac->RA_RAPID_found) { uint8_t freq_hopping, mcs, Msg3_t_alloc, Msg3_f_alloc; - unsigned char tpc_command, csi_req; + unsigned char tpc_command; +#ifdef DEBUG_RAR + unsigned char csi_req; +#endif // TC-RNTI *t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); ue_mac->t_crnti = *t_crnti; // TA command ta_command = rar->TA2 + (rar->TA1 << 5); + +#ifdef DEBUG_RAR // CSI csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01); +#endif + // TPC tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07); switch (tpc_command){ diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 6bd7940480..ab49fcdc8c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -125,14 +125,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm } lte_frame_type_t frame_type; - uint16_t band; - int32_t offset; - - get_band((cfg->carrier_config.dl_frequency.value)*1000, - &band, - &offset, - &frame_type); - + get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type); RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type; // Cell configuration @@ -297,8 +290,8 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm "scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n"); cfg->tdd_table.tdd_period.value = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530; } - LOG_I(MAC,"Setting TDD configuration period to %d\n",cfg->tdd_table.tdd_period.value); if(cfg->cell_config.frame_duplex_type.value == TDD){ + LOG_I(MAC,"Setting TDD configuration period to %d\n",cfg->tdd_table.tdd_period.value); int return_tdd = set_tdd_config_nr(cfg, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots, @@ -306,15 +299,16 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots, scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols); - if (return_tdd !=0){ - LOG_E(PHY,"TDD configuration can not be done\n"); - } - else LOG_I(PHY,"TDD has been properly configurated\n"); + if (return_tdd != 0) + LOG_E(MAC,"TDD configuration can not be done\n"); + else + LOG_I(MAC,"TDD has been properly configurated\n"); } } + int rrc_mac_config_req_gNB(module_id_t Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, @@ -367,6 +361,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, if (add_ue == 1 && get_softmodem_params()->phy_test) { const int UE_id = add_new_nr_ue(Mod_idP,rnti); UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup; + compute_csi_bitlen (secondaryCellGroup, UE_info, UE_id); struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList; AssertFatal(bwpList->list.count == 1, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 63ca351911..5d701bf5b8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -344,9 +344,8 @@ void nr_schedule_pucch(int Mod_idP, frame_t frameP, sub_frame_t slotP) { - uint16_t O_uci; - uint16_t O_ack; - uint8_t SR_flag = 0; // no SR in PUCCH implemented for now + uint16_t O_csi, O_ack, O_uci; + uint8_t O_sr = 0; // no SR in PUCCH implemented for now NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id); @@ -359,31 +358,36 @@ void nr_schedule_pucch(int Mod_idP, NR_sched_pucch *curr_pucch; for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k]; - if ((curr_pucch->dai_c > 0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) { - UL_tti_req->SFN = curr_pucch->frame; - UL_tti_req->Slot = curr_pucch->ul_slot; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t); - nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu; - memset(pucch_pdu,0,sizeof(nfapi_nr_pucch_pdu_t)); - UL_tti_req->n_pdus+=1; + for (int l=0; l<2; l++) { + curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l]; O_ack = curr_pucch->dai_c; - O_uci = O_ack; // for now we are just sending acknacks in pucch + O_csi = curr_pucch->csi_bits; + O_uci = O_ack + O_csi + O_sr; + if ((O_uci>0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) { + UL_tti_req->SFN = curr_pucch->frame; + UL_tti_req->Slot = curr_pucch->ul_slot; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t); + nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu; + memset(pucch_pdu,0,sizeof(nfapi_nr_pucch_pdu_t)); + UL_tti_req->n_pdus+=1; - LOG_D(MAC, "Scheduling pucch reception for frame %d slot %d\n", frameP, slotP); + LOG_D(MAC,"Scheduling pucch reception for frame %d slot %d with (%d, %d, %d) (SR ACK, CSI) bits\n", + frameP,slotP,O_sr,O_ack,curr_pucch->csi_bits); - nr_configure_pucch(pucch_pdu, - scc, - ubwp, - curr_pucch->resource_indicator, - O_uci, - O_ack, - SR_flag); + nr_configure_pucch(pucch_pdu, + scc, + ubwp, + UE_info->rnti[UE_id], + curr_pucch->resource_indicator, + O_csi, + O_ack, + O_sr); - memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k], - 0, - sizeof(NR_sched_pucch)); + memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l], + 0, + sizeof(NR_sched_pucch)); + } } } } @@ -395,9 +399,12 @@ bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) { void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_t slot){ + protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP); + int nb_periods_per_frame; + const int UE_id = 0; const int bwp_id = 1; @@ -406,24 +413,49 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id]; NR_COMMON_channels_t *cc = gNB->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; - const int num_slots_per_tdd = slots_per_frame[*scc->ssbSubcarrierSpacing] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity); - const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0); - if (slot == 0 && UE_info->active[UE_id]) { - for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k], - 0, - sizeof(NR_sched_pucch));*/ - /* Seems to be covered in line 335? */ - /*memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k], - 0, - sizeof(NR_sched_pusch));*/ - } + switch(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity) { + case 0: + nb_periods_per_frame = 20; // 10ms/0p5ms + break; + + case 1: + nb_periods_per_frame = 16; // 10ms/0p625ms + break; + + case 2: + nb_periods_per_frame = 10; // 10ms/1ms + break; + + case 3: + nb_periods_per_frame = 8; // 10ms/1p25ms + break; + + case 4: + nb_periods_per_frame = 5; // 10ms/2ms + break; + + case 5: + nb_periods_per_frame = 4; // 10ms/2p5ms + break; + + case 6: + nb_periods_per_frame = 2; // 10ms/5ms + break; + + case 7: + nb_periods_per_frame = 1; // 10ms/10ms + break; + + default: + AssertFatal(1==0,"Undefined tdd period %ld\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); } + int num_slots_per_tdd = (slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame; + + const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0); + start_meas(&RC.nrmac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); @@ -446,18 +478,18 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, //mbsfn_status[CC_id] = 0; // clear vrb_maps - memset(cc[CC_id].vrb_map, 0, 275); - memset(cc[CC_id].vrb_map_UL, 0, 275); + memset(cc[CC_id].vrb_map, 0, sizeof(uint16_t) * 275); + memset(cc[CC_id].vrb_map_UL, 0, sizeof(uint16_t) * 275); clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot); } + if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]); + // This schedules MIB - if((slot == 0) && (frame & 7) == 0){ - schedule_nr_mib(module_idP, frame, slot); - } + schedule_nr_mib(module_idP, frame, slot, slots_per_frame[*scc->ssbSubcarrierSpacing]); // This schedule PRACH if we are not in phy_test mode if (get_softmodem_params()->phy_test == 0) @@ -466,8 +498,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, // This schedule SR // TODO - // This schedule CSI - // TODO + // This schedule CSI measurement reporting + if (UE_info->active[UE_id]) + nr_csi_meas_reporting(module_idP, UE_id, frame, slot, num_slots_per_tdd, nr_ulmix_slots, slots_per_frame[*scc->ssbSubcarrierSpacing]); // This schedule RA procedure if not in phy_test mode // Otherwise already consider 5G already connected @@ -475,40 +508,30 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, if (get_softmodem_params()->phy_test == 0) { nr_schedule_RA(module_idP, frame, slot); nr_schedule_reception_msg3(module_idP, 0, frame, slot); - } - if (UE_info->active[UE_id]) { - // TbD once RACH is available, start ta_timer when UE is connected - if (ue_sched_ctl->ta_timer) - ue_sched_ctl->ta_timer--; - if (ue_sched_ctl->ta_timer == 0) { - ue_sched_ctl->ta_apply = true; - /* if time is up, then set the timer to not send it for 5 frames - // regardless of the TA value */ - ue_sched_ctl->ta_timer = 100; - } } // This schedules the DCI for Uplink and subsequently PUSCH + // The decision about whether to schedule is done for each UE independently // inside if (UE_info->active[UE_id] && slot < 10) { + int tda = 1; // time domain assignment hardcoded for now schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda, ulsch_in_slot_bitmap); nr_schedule_pusch(module_idP, UE_id, num_slots_per_tdd, nr_ulmix_slots, frame, slot); } + if (UE_info->active[UE_id] && (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd)) && slot < 10) { + ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd; - //int pucch_sched; - //nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched); - //nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_info->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL); nr_schedule_ue_spec(module_idP, frame, slot, num_slots_per_tdd); - ue_sched_ctl->ta_apply = false; } + if (UE_info->active[UE_id]) nr_schedule_pucch(module_idP, UE_id, nr_ulmix_slots, frame, slot); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index af40c9ccd8..66dcfcff86 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -70,7 +70,7 @@ int16_t ssb_index_from_prach(module_id_t module_idP, float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value]; uint16_t start_symbol_index = 0; - uint8_t mu,N_dur,N_t_slot,start_symbol = 0, temp_start_symbol = 0, N_RA_slot; + uint8_t mu,N_dur=0,N_t_slot=0,start_symbol = 0, temp_start_symbol = 0, N_RA_slot=0; uint16_t format,RA_sfn_index = -1; uint8_t config_period = 1; uint16_t prach_occasion_id = -1; @@ -139,7 +139,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) { nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; - uint8_t mu,N_dur,N_t_slot,start_symbol,N_RA_slot = 0; + uint8_t mu,N_dur=0,N_t_slot=0,start_symbol=0,N_RA_slot = 0; uint16_t format,N_RA_sfn = 0,unused_RA_occasion,repetition = 0; uint8_t num_active_ssb = 0; uint8_t max_association_period = 1; @@ -421,14 +421,23 @@ void nr_initiate_ra_proc(module_id_t module_idP, uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL NR_SearchSpace_t *ss; - // ra_rnti from 5.1.3 in 38.321 - uint16_t ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_RA_t *ra = &cc->ra[0]; + + uint16_t ra_rnti; + + // ra_rnti from 5.1.3 in 38.321 + // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here. + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present==NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839) + ra_rnti=1+symbol+(9/*slotP*/*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); + else + ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); + + // if the preamble received correspond to one of the listed // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries int pr_found=0; @@ -438,9 +447,11 @@ void nr_initiate_ra_proc(module_id_t module_idP, break; } } + if (!pr_found) { LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", module_idP, preamble_index); + return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc } // This should be handled differently when we use the initialBWP for RA @@ -921,8 +932,12 @@ void nr_generate_Msg2(module_id_t module_idP, nr_mac->TX_req[CC_id].Slot = slotP; memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length); + T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), + T_INT(RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */, + T_BUFFER(&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length)); + /* mark the corresponding RBs as used */ - uint8_t *vrb_map = cc[CC_id].vrb_map; + uint16_t *vrb_map = cc[CC_id].vrb_map; for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index daa1fd9c82..b0f2d2f68c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -56,7 +56,7 @@ extern RAN_CONTEXT_t RC; extern uint8_t SSB_Table[38]; -void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ +void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, uint8_t slots_per_frame){ gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc; @@ -67,93 +67,150 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ int mib_sdu_length; int CC_id; - AssertFatal(slotP == 0, "Subframe must be 0\n"); - AssertFatal((frameP & 7) == 0, "Frame must be a multiple of 8\n"); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - - nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; - dl_tti_request = &gNB->DL_req[CC_id]; - dl_req = &dl_tti_request->dl_tti_request_body; cc = &gNB->common_channels[CC_id]; -#if 0 - //SSB is transmitted based on SSB periodicity - if((frameP % cfg->ssb_table.ssb_period.value) == 0) { - uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ; - uint32_t ssb_index = -1; - for (int i=0; i<2; i++) { // max two SSB per slot - ssb_index = i + SSB_Table[slotP]; // computing the ssb_index - if ((ssb_index<64) && ((L_ssb >> (63-ssb_index)) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1 -#endif + const long band = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + const uint32_t ssb_offset0 = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; + int ratio; + switch (*cc->ServingCellConfigCommon->ssbSubcarrierSpacing) { + case NR_SubcarrierSpacing_kHz15: + AssertFatal(band <= 79, + "Band %ld is not possible for SSB with 15 kHz SCS\n", + band); + if (band < 77) // below 3GHz + ratio = 3; // NRARFCN step is 5 kHz + else + ratio = 1; // NRARFCN step is 15 kHz + break; + case NR_SubcarrierSpacing_kHz30: + AssertFatal(band <= 79, + "Band %ld is not possible for SSB with 15 kHz SCS\n", + band); + if (band < 77) // below 3GHz + ratio = 6; // NRARFCN step is 5 kHz + else + ratio = 2; // NRARFCN step is 15 kHz + break; + case NR_SubcarrierSpacing_kHz120: + AssertFatal(band >= 257, + "Band %ld is not possible for SSB with 120 kHz SCS\n", + band); + ratio = 2; // NRARFCN step is 15 kHz + break; + case NR_SubcarrierSpacing_kHz240: + AssertFatal(band >= 257, + "Band %ld is not possible for SSB with 240 kHz SCS\n", + band); + ratio = 4; // NRARFCN step is 15 kHz + break; + default: + AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n", + *cc->ServingCellConfigCommon->ssbSubcarrierSpacing); + } - mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]); // not used in this case + // scheduling MIB every 8 frames, PHY repeats it in between + if((slotP == 0) && (frameP & 7) == 0) { + dl_tti_request = &gNB->DL_req[CC_id]; + dl_req = &dl_tti_request->dl_tti_request_body; - LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length); + mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]); - if (mib_sdu_length > 0) { + LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length); - LOG_D(MAC, "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", frameP, slotP, dl_req->nPDUs, mib_sdu_length); + if (mib_sdu_length > 0) { + LOG_D(MAC, + "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", + frameP, + slotP, + dl_req->nPDUs, + mib_sdu_length); - if ((frameP & 1023) < 80){ - LOG_I(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length); + if ((frameP & 1023) < 80){ + LOG_I(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length); + } + + dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE; + dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t); + + AssertFatal(cc->ServingCellConfigCommon->physCellId!=NULL,"cc->ServingCellConfigCommon->physCellId is null\n"); + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *cc->ServingCellConfigCommon->physCellId; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0; + AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n"); + AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n"); + AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n"); + AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count); + AssertFatal(cc->ServingCellConfigCommon->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n"); + AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n"); + + const nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1); + dl_req->nPDUs++; } + } - dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE; - dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t); - - AssertFatal(cc->ServingCellConfigCommon->physCellId!=NULL,"cc->ServingCellConfigCommon->physCellId is null\n"); - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *cc->ServingCellConfigCommon->physCellId; - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0; - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;//ssb_index ;//SSB index for each SSB - AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n"); - AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n"); - AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n"); - AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count); - AssertFatal(cc->ServingCellConfigCommon->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n"); - AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n"); - long band = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - uint32_t ssb_offset0 = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; - int ratio; - switch (*cc->ServingCellConfigCommon->ssbSubcarrierSpacing) { - case NR_SubcarrierSpacing_kHz15: - AssertFatal(band <= 79, "Band %ld is not possible for SSB with 15 kHz SCS\n",band); - if (band<77) // below 3GHz - ratio=3; // NRARFCN step is 5 kHz - else - ratio=1; // NRARFCN step is 15 kHz - break; - case NR_SubcarrierSpacing_kHz30: - AssertFatal(band <= 79, "Band %ld is not possible for SSB with 15 kHz SCS\n",band); - if (band<77) // below 3GHz - ratio=6; // NRARFCN step is 5 kHz - else - ratio=2; // NRARFCN step is 15 kHz - break; - case NR_SubcarrierSpacing_kHz120: - AssertFatal(band >= 257, "Band %ld is not possible for SSB with 120 kHz SCS\n",band); - ratio=2; // NRARFCN step is 15 kHz - break; - case NR_SubcarrierSpacing_kHz240: - AssertFatal(band >= 257, "Band %ld is not possible for SSB with 240 kHz SCS\n",band); - ratio=4; // NRARFCN step is 15 kHz - break; - default: - AssertFatal(1==0,"SCS %ld not allowed for SSB \n", *cc->ServingCellConfigCommon->ssbSubcarrierSpacing); - } - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10;/*cfg->ssb_table.ssb_offset_point_a.value;*/ // absoluteFrequencySSB is the center of SSB - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1; - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1); - dl_req->nPDUs++; - - uint8_t *vrb_map = cc[CC_id].vrb_map; - const int rbStart = dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA; - for (int rb = 0; rb < 20; rb++) - vrb_map[rbStart + rb] = 1; + // checking if there is any SSB in slot + const int abs_slot = (slots_per_frame * frameP) + slotP; + const int slot_per_period = (slots_per_frame>>1)<<(*cc->ServingCellConfigCommon->ssb_periodicityServingCell); + int eff_120_slot; + const BIT_STRING_t *shortBitmap = &cc->ServingCellConfigCommon->ssb_PositionsInBurst->choice.shortBitmap; + const BIT_STRING_t *mediumBitmap = &cc->ServingCellConfigCommon->ssb_PositionsInBurst->choice.mediumBitmap; + const BIT_STRING_t *longBitmap = &cc->ServingCellConfigCommon->ssb_PositionsInBurst->choice.longBitmap; + uint8_t buf = 0; + switch (cc->ServingCellConfigCommon->ssb_PositionsInBurst->present) { + case 1: + // presence of ssbs possible in the first 2 slots of ssb period + if ((abs_slot % slot_per_period) < 2 && + (((shortBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0) + fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id); + break; + case 2: + // presence of ssbs possible in the first 4 slots of ssb period + if ((abs_slot % slot_per_period) < 4 && + (((mediumBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0) + fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id); + break; + case 3: + AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing == + NR_SubcarrierSpacing_kHz120, + "240kHZ subcarrier spacing currently not supported for SSBs\n"); + if ((abs_slot % slot_per_period) < 8) { + eff_120_slot = slotP; + buf = longBitmap->buf[0]; + } else if ((abs_slot % slot_per_period) < 17) { + eff_120_slot = slotP - 9; + buf = longBitmap->buf[1]; + } else if ((abs_slot % slot_per_period) < 26) { + eff_120_slot = slotP - 18; + buf = longBitmap->buf[2]; + } else if ((abs_slot % slot_per_period) < 35) { + eff_120_slot = slotP - 27; + buf = longBitmap->buf[3]; + } + if (((buf >> (6 - (eff_120_slot << 1))) & 3) != 0) + fill_ssb_vrb_map(cc, ssb_offset0 / (ratio * 12) - 10, CC_id); + break; + default: + AssertFatal(0, + "SSB bitmap size value %d undefined (allowed values 1,2,3)\n", + cc->ServingCellConfigCommon->ssb_PositionsInBurst->present); } } } +void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { +//---------------------------------------- +} + +void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id) { + uint16_t *vrb_map = cc[CC_id].vrb_map; + for (int rb = 0; rb < 20; rb++) + vrb_map[rbStart + rb] = 1; +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 4c6558d4f6..7a7fe1288c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -343,68 +343,98 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, return offset; } -void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10) { +void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch, + nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01, + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234, + NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) { + // TODO int max_harq_rounds = 4; // TODO define macro - int num_ucis = UL_info->uci_ind.num_ucis; - nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list; - for (int i = 0; i < num_ucis; i++) { - switch (uci_list[i].pdu_type) { - case NFAPI_NR_UCI_PDCCH_PDU_TYPE: break; + if (uci_01 != NULL) { + // handle harq + int harq_idx_s = 0; - case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { - //if (get_softmodem_params()->phy_test == 0) { - nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1; - // handle harq - int harq_idx_s = 0; - // tpc (power control) - sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30); - // iterate over received harq bits - for (int harq_bit = 0; harq_bit < uci_pdu->harq->num_harq; harq_bit++) { - // search for the right harq process - for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES; harq_idx++) { - // if the gNB received ack with a good confidence - if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) { - if ((uci_pdu->harq->harq_list[harq_bit].harq_value == 1) && - (uci_pdu->harq->harq_confidence_level == 0)) { - // toggle NDI and reset round - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - } - else - sched_ctrl->harq_processes[harq_idx].round++; - sched_ctrl->harq_processes[harq_idx].is_waiting = 0; - harq_idx_s = harq_idx + 1; - // if the max harq rounds was reached - if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - stats->dlsch_errors++; - } - break; - } - // if feedback slot processing is aborted - else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) && - (sched_ctrl->harq_processes[harq_idx].is_waiting)) { - sched_ctrl->harq_processes[harq_idx].round++; - if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - } - sched_ctrl->harq_processes[harq_idx].is_waiting = 0; - } - } + // iterate over received harq bits + for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) { + // search for the right harq process + for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES; harq_idx++) { + // if the gNB received ack with a good confidence + if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) { + if ((uci_01->harq->harq_list[harq_bit].harq_value == 1) && + (uci_01->harq->harq_confidence_level == 0)) { + // toggle NDI and reset round + sched_ctrl->harq_processes[harq_idx].ndi ^= 1; + sched_ctrl->harq_processes[harq_idx].round = 0; } - //} - break; + else + sched_ctrl->harq_processes[harq_idx].round++; + sched_ctrl->harq_processes[harq_idx].is_waiting = 0; + harq_idx_s = harq_idx + 1; + // if the max harq rounds was reached + if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { + sched_ctrl->harq_processes[harq_idx].ndi ^= 1; + sched_ctrl->harq_processes[harq_idx].round = 0; + stats->dlsch_errors++; + } + break; + } + // if feedback slot processing is aborted + else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) && + (sched_ctrl->harq_processes[harq_idx].is_waiting)) { + sched_ctrl->harq_processes[harq_idx].round++; + if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { + sched_ctrl->harq_processes[harq_idx].ndi ^= 1; + sched_ctrl->harq_processes[harq_idx].round = 0; + } + sched_ctrl->harq_processes[harq_idx].is_waiting = 0; + } } - - case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: break; } } - UL_info->uci_ind.num_ucis = 0; + + if (uci_234 != NULL) { + int harq_idx_s = 0; + int acknack; + + // iterate over received harq bits + for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) { + acknack = ((uci_234->harq.harq_payload[harq_bit>>3])>>harq_bit)&0x01; + for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) { + // if the gNB received ack with a good confidence or if the max harq rounds was reached + if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) { + // TODO add some confidence level for when there is no CRC + if ((uci_234->harq.harq_crc != 1) && acknack) { + // toggle NDI and reset round + sched_ctrl->harq_processes[harq_idx].ndi ^= 1; + sched_ctrl->harq_processes[harq_idx].round = 0; + } + else + sched_ctrl->harq_processes[harq_idx].round++; + sched_ctrl->harq_processes[harq_idx].is_waiting = 0; + harq_idx_s = harq_idx + 1; + // if the max harq rounds was reached + if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { + sched_ctrl->harq_processes[harq_idx].ndi ^= 1; + sched_ctrl->harq_processes[harq_idx].round = 0; + stats->dlsch_errors++; + } + break; + } + // if feedback slot processing is aborted + else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) && + (sched_ctrl->harq_processes[harq_idx].is_waiting)) { + sched_ctrl->harq_processes[harq_idx].round++; + if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { + sched_ctrl->harq_processes[harq_idx].ndi ^= 1; + sched_ctrl->harq_processes[harq_idx].round = 0; + } + sched_ctrl->harq_processes[harq_idx].is_waiting = 0; + } + } + } + } } int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda) { @@ -453,7 +483,6 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id, const int CC_id = 0; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - sched_ctrl->rbSize = 0; /* Retrieve amount of data to send for this UE */ sched_ctrl->num_total_bytes = 0; @@ -470,7 +499,8 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id, 0, 0); sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; - if (sched_ctrl->num_total_bytes == 0 && !get_softmodem_params()->phy_test) + if (sched_ctrl->num_total_bytes == 0 + && !sched_ctrl->ta_apply) /* If TA should be applied, give at least one RB */ return; LOG_D(MAC, "%d.%d, DTCH%d->DLSCH, RLC status %d bytes\n", @@ -505,11 +535,17 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id, UE_info->num_pdcch_cand[UE_id][cid]++; /* Find PUCCH occasion */ - nr_update_pucch_scheduling( - module_id, UE_id, frame, slot, num_slots_per_tdd, &sched_ctrl->pucch_sched_idx); + nr_acknack_scheduling(module_id, + UE_id, + frame, + slot, + num_slots_per_tdd, + &sched_ctrl->pucch_sched_idx, + &sched_ctrl->pucch_occ_idx); + AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n"); - uint8_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; + uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; const int current_harq_pid = sched_ctrl->current_harq_pid; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid]; @@ -589,18 +625,26 @@ void nr_schedule_ue_spec(module_id_t module_id, frame_t frame, sub_frame_t slot, int num_slots_per_tdd) { - /* PREPROCESSOR */ - nr_simple_dlsch_preprocessor(module_id, frame, slot, num_slots_per_tdd); - gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; + + /* PREPROCESSOR */ + gNB_mac->pre_processor_dl(module_id, frame, slot, num_slots_per_tdd); + NR_UE_info_t *UE_info = &gNB_mac->UE_info; const int CC_id = 0; - NR_UE_list_t *UE_list = &UE_info->list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - if (sched_ctrl->rbSize <= 0 && !get_softmodem_params()->phy_test) + + /* update TA and set ta_apply every 10 frames. + * Possible improvement: take the periodicity from input file. + * If such UE is not scheduled now, it will be by the preprocessor later. + * If we add the CE, ta_apply will be reset */ + if (frame == (sched_ctrl->ta_frame + 10) % 1024) + sched_ctrl->ta_apply = false; /* the timer is reset once TA CE is scheduled */ + + if (sched_ctrl->rbSize <= 0) continue; const rnti_t rnti = UE_info->rnti[UE_id]; @@ -634,34 +678,24 @@ void nr_schedule_ue_spec(module_id_t module_id, const int current_harq_pid = sched_ctrl->current_harq_pid; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; - NR_sched_pucch *pucch = &sched_ctrl->sched_pucch[sched_ctrl->pucch_sched_idx]; + NR_sched_pucch *pucch = &sched_ctrl->sched_pucch[sched_ctrl->pucch_sched_idx][sched_ctrl->pucch_occ_idx]; harq->feedback_slot = pucch->ul_slot; harq->is_waiting = 1; UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++; nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; nr_fill_nfapi_dl_pdu(module_id, - UE_id, - sched_ctrl->active_bwp->bwp_Id, - sched_ctrl->search_space, - sched_ctrl->coreset, dl_req, + rnti, + UE_info->secondaryCellGroup[UE_id], + sched_ctrl, pucch, - 1 /* nrOfLayers */, - sched_ctrl->mcs, - sched_ctrl->rbSize, - sched_ctrl->rbStart, - sched_ctrl->numDmrsCdmGrpsNoData, getDmrsConfigType(sched_ctrl->active_bwp), - sched_ctrl->mcsTableIdx, nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), TBS, - sched_ctrl->time_domain_allocation, startSymbolIndex, nrOfSymbols, - sched_ctrl->aggregation_level, - sched_ctrl->cce_index, current_harq_pid, harq->ndi, harq->round); @@ -698,7 +732,7 @@ void nr_schedule_ue_spec(module_id_t module_id, * nr_generate_dlsch_pdu() checks for ta_apply and add TA CE if necessary */ const int ta_len = (sched_ctrl->ta_apply) ? 2 : 0; - /* Get RLC data TODO: remove random data retrieval */ + /* Get RLC data */ int header_length_total = 0; int header_length_last = 0; int sdu_length_total = 0; @@ -740,10 +774,7 @@ void nr_schedule_ue_spec(module_id_t module_id, sdu_length_total += sdu_lengths[num_sdus]; header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); header_length_total += header_length_last; - num_sdus++; - - //ue_sched_ctl->uplane_inactivity_timer = 0; } else if (get_softmodem_params()->phy_test) { LOG_D(MAC, "Configuring DL_TX in %d.%d: random data\n", frame, slot); @@ -760,10 +791,7 @@ void nr_schedule_ue_spec(module_id_t module_id, UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS; UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total; - // Check if there is data from RLC or CE const int post_padding = TBS >= 2 + header_length_total + sdu_length_total + ta_len; - // padding param currently not in use - //padding = TBS - header_length_total - sdu_length_total - ta_len - 1; const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; @@ -804,6 +832,20 @@ void nr_schedule_ue_spec(module_id_t module_id, retInfo->mcs = sched_ctrl->mcs; retInfo->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData; + // ta command is sent, values are reset + if (sched_ctrl->ta_apply) { + sched_ctrl->ta_apply = false; + sched_ctrl->ta_frame = frame; + LOG_D(MAC, + "%d.%2d UE %d TA scheduled, resetting TA frame\n", + frame, + slot, + UE_id); + } + + T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), + T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(buf, TBS)); + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) if (frame%100 == 0) { LOG_I(MAC, @@ -816,5 +858,8 @@ void nr_schedule_ue_spec(module_id_t module_id, } #endif } + + /* mark UE as scheduled */ + sched_ctrl->rbSize = 0; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 4ee4e29213..e14afacf09 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -252,240 +252,104 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, } } -int configure_fapi_dl_pdu_phytest(int Mod_idP, - nfapi_nr_dl_tti_request_body_t *dl_req, - NR_sched_pucch *pucch_sched, - uint8_t *mcsIndex, - uint16_t *rbSize, - uint16_t *rbStart) { - gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; - NR_COMMON_channels_t *cc = nr_mac->common_channels; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; +/* schedules whole bandwidth for first user, all the time */ +void nr_preprocessor_phytest(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd) +{ + if (slot != 1) + 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; + const int CC_id = 0; + AssertFatal(UE_info->active[UE_id], + "%s(): expected UE %d to be active\n", + __func__, + UE_id); - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu; - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu; - - int TBS; - int bwp_id=1; - int UE_id = 0; - - NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - - NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; - AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", - secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); - NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; - - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, - "searchPsacesToAddModList is empty\n"); - - dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; - dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); - - dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1]; - memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; - dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); - - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - - - pdsch_pdu_rel15->pduBitmap = 0; - pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id]; - pdsch_pdu_rel15->pduIndex = 0; - - // BWP - pdsch_pdu_rel15->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); - pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); - pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; - if (bwp->bwp_Common->genericParameters.cyclicPrefix) pdsch_pdu_rel15->CyclicPrefix = *bwp->bwp_Common->genericParameters.cyclicPrefix; - else pdsch_pdu_rel15->CyclicPrefix=0; - - pdsch_pdu_rel15->NrOfCodewords = 1; - int mcs = (mcsIndex!=NULL) ? *mcsIndex : 9; - int current_harq_pid = UE_info->UE_sched_ctrl[UE_id].current_harq_pid; - pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcs,0); - pdsch_pdu_rel15->qamModOrder[0] = 2; - pdsch_pdu_rel15->mcsIndex[0] = mcs; - pdsch_pdu_rel15->mcsTable[0] = 0; - pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]; - pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; - pdsch_pdu_rel15->nrOfLayers = 1; - pdsch_pdu_rel15->transmissionScheme = 0; - pdsch_pdu_rel15->refPoint = 0; // Point A - UE_info->mac_stats[UE_id].dlsch_rounds[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++; - pdsch_pdu_rel15->dmrsConfigType = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; - pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; - pdsch_pdu_rel15->SCID = 0; - pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 1; - pdsch_pdu_rel15->dmrsPorts = 1; - pdsch_pdu_rel15->resourceAlloc = 1; - pdsch_pdu_rel15->rbStart = (rbStart!=NULL) ? *rbStart : 0; - pdsch_pdu_rel15->rbSize = (rbSize!=NULL) ? *rbSize : pdsch_pdu_rel15->BWPSize; - pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP - - int startSymbolAndLength=0; - int time_domain_assignment=2; - int StartSymbolIndex,NrOfSymbols; - - AssertFatal(time_domain_assignmentbwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count,"time_domain_assignment %d>=%d\n",time_domain_assignment,bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count); - startSymbolAndLength = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength,&StartSymbolIndex,&NrOfSymbols); - pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; - pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; - - // k0 = *bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0; - pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, - scc->dmrs_TypeA_Position, - pdsch_pdu_rel15->NrOfSymbols); - - dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t)); - - // bwp indicator - int n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; - if (n_dl_bwp < 4) - dci_pdu_rel15[0].bwp_indicator.val = bwp_id; - else - dci_pdu_rel15[0].bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212 - // frequency domain assignment - if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation==NR_PDSCH_Config__resourceAllocation_resourceAllocationType1) - dci_pdu_rel15[0].frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->rbStart, - NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275)); - else - AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); - // time domain assignment - dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; // row index used here instead of SLIV; - // mcs and rv - dci_pdu_rel15[0].mcs = pdsch_pdu_rel15->mcsIndex[0]; - dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0]; - // harq pid and ndi - dci_pdu_rel15[0].harq_pid = current_harq_pid; - dci_pdu_rel15[0].ndi = UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].ndi; - // DAI - dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3; - - // TPC for PUCCH - dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213 - // PUCCH resource indicator - dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator; - // PDSCH to HARQ TI - dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = pucch_sched->timing_indicator; - UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].feedback_slot = pucch_sched->ul_slot; - UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].is_waiting = 1; - // antenna ports - dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0 - // dmrs sequence initialization - dci_pdu_rel15[0].dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID; - LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", - dci_pdu_rel15[0].frequency_domain_assignment.val, - pdsch_pdu_rel15->rbStart, - pdsch_pdu_rel15->rbSize, - NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), - dci_pdu_rel15[0].time_domain_assignment.val, - dci_pdu_rel15[0].vrb_to_prb_mapping.val, - dci_pdu_rel15[0].mcs, - dci_pdu_rel15[0].tb_scaling, - dci_pdu_rel15[0].ndi, - dci_pdu_rel15[0].rv); - - NR_SearchSpace_t *ss; - int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, - "searchPsacesToAddModList is empty\n"); - - int found=0; - - for (int i=0;ibwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { - ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; - AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); - AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); - if (ss->searchSpaceType->present == target_ss) { - found=1; - break; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + /* find largest unallocated chunk */ + const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275); + int rbStart = 0; + int tStart = 0; + int rbSize = 0; + uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; + /* find largest unallocated RB region */ + do { + /* advance to first free RB */ + while (tStart < bwpSize && vrb_map[tStart]) + tStart++; + /* find maximum rbSize at current rbStart */ + int tSize = 1; + while (tStart + tSize < bwpSize && !vrb_map[tStart + tSize]) + tSize++; + if (tSize > rbSize) { + rbStart = tStart; + rbSize = tSize; } - } - AssertFatal(found==1,"Couldn't find an adequate searchspace\n"); + tStart += tSize; + } while (tStart < bwpSize); - uint8_t nr_of_candidates, aggregation_level; - find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); - NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */); - const int cid = coreset->controlResourceSetId; - const uint16_t Y = UE_info->Y[UE_id][cid][nr_mac->current_slot]; + sched_ctrl->num_total_bytes = 0; + const int lcid = DL_SCH_LCID_DTCH; + const uint16_t rnti = UE_info->rnti[UE_id]; + /* update sched_ctrl->num_total_bytes so that postprocessor schedules data, + * if available */ + sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id, + rnti, + module_id, + frame, + slot, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + 0, + 0); + sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; + + const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss); + uint8_t nr_of_candidates; + find_aggregation_candidates(&sched_ctrl->aggregation_level, + &nr_of_candidates, + sched_ctrl->search_space); + sched_ctrl->coreset = get_coreset( + sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); + const int cid = sched_ctrl->coreset->controlResourceSetId; + const uint16_t Y = UE_info->Y[UE_id][cid][RC.nrmac[module_id]->current_slot]; const int m = UE_info->num_pdcch_cand[UE_id][cid]; - int CCEIndex = allocate_nr_CCEs(nr_mac, - bwp, - coreset, - aggregation_level, + sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id], + sched_ctrl->active_bwp, + sched_ctrl->coreset, + sched_ctrl->aggregation_level, Y, m, nr_of_candidates); - if (CCEIndex < 0) { - LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PDSCH\n", __func__); - free(dci_pdu_rel15); - return 0; - } - UE_info->num_pdcch_cand[UE_id][cid]++; + AssertFatal(sched_ctrl->cce_index >= 0, + "%s(): could not find CCE for UE %d\n", + __func__, + UE_id); - nr_configure_pdcch(nr_mac, - pdcch_pdu_rel15, - UE_info->rnti[UE_id], - ss, - coreset, - scc, - bwp, - aggregation_level, - CCEIndex); + nr_acknack_scheduling(module_id, + UE_id, + frame, + slot, + num_slots_per_tdd, + &sched_ctrl->pucch_sched_idx, + &sched_ctrl->pucch_occ_idx); + AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n"); - int dci_formats[2]; - int rnti_types[2]; - - if (ss->searchSpaceType->choice.ue_Specific->dci_Formats) - dci_formats[0] = NR_DL_DCI_FORMAT_1_1; - else - dci_formats[0] = NR_DL_DCI_FORMAT_1_0; + sched_ctrl->rbStart = rbStart; + sched_ctrl->rbSize = rbSize; + sched_ctrl->time_domain_allocation = 2; + sched_ctrl->mcsTableIdx = 0; + sched_ctrl->mcs = 9; + sched_ctrl->numDmrsCdmGrpsNoData = 1; - rnti_types[0] = NR_RNTI_C; - - fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,bwp_id); - - LOG_D(MAC, "DCI params: rnti %x, rnti_type %d, dci_format %d\n \ - coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", - pdcch_pdu_rel15->dci_pdu.RNTI[0], - rnti_types[0], - dci_formats[0], - (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, - pdcch_pdu_rel15->StartSymbolIndex, - pdcch_pdu_rel15->DurationSymbols); - - int x_Overhead = 0; // should be 0 for initialBWP - nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu,x_Overhead,pdsch_pdu_rel15->numDmrsCdmGrpsNoData,0); - - // Hardcode it for now - TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]; - if (UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0) - UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS; - - LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d startSymbolAndLength %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n", - pdsch_pdu_rel15->rbStart, - pdsch_pdu_rel15->rbSize, - startSymbolAndLength, - pdsch_pdu_rel15->StartSymbolIndex, - pdsch_pdu_rel15->NrOfSymbols, - pdsch_pdu_rel15->nrOfLayers, - pdsch_pdu_rel15->NrOfCodewords, - pdsch_pdu_rel15->mcsIndex[0], - TBS); - - free(dci_pdu_rel15); - return TBS; //Return TBS in bytes + /* mark the corresponding RBs as used */ + for (int rb = 0; rb < sched_ctrl->rbSize; rb++) + vrb_map[rb + sched_ctrl->rbStart] = 1; } void config_uldci(NR_BWP_Uplink_t *ubwp, @@ -564,231 +428,6 @@ void config_uldci(NR_BWP_Uplink_t *ubwp, } - -void configure_fapi_dl_Tx(module_id_t Mod_idP, - frame_t frameP, - sub_frame_t slotP, - nfapi_nr_dl_tti_request_body_t *dl_req, - nfapi_nr_pdu_t *tx_req, - int tbs_bytes, - int16_t pdu_index){ - - int CC_id = 0; - - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1]; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; - - LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS (bytes): %d\n", - pdsch_pdu_rel15->rbStart, - pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->StartSymbolIndex, - pdsch_pdu_rel15->NrOfSymbols, - pdsch_pdu_rel15->nrOfLayers, - pdsch_pdu_rel15->NrOfCodewords, - pdsch_pdu_rel15->mcsIndex[0], - tbs_bytes); - - dl_req->nPDUs+=2; - - tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0]; - tx_req->PDU_index = nr_mac->pdu_index[0]++; - tx_req->num_TLV = 1; - tx_req->TLVs[0].length = tbs_bytes +2; - - memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_info.DLSCH_pdu[0][0].payload[0], tbs_bytes); - - nr_mac->TX_req[CC_id].Number_of_PDUs++; - nr_mac->TX_req[CC_id].SFN = frameP; - nr_mac->TX_req[CC_id].Slot = slotP; -} - -void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, - frame_t frameP, - sub_frame_t slotP, - NR_sched_pucch *pucch_sched, - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dlsch_config){ - - LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest frame %d slot %d\n",frameP,slotP); - - int post_padding = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; - int lcid, offset, i, header_length_last, TBS_bytes = 0; - int UE_id = 0, CC_id = 0; - - gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; - //NR_COMMON_channels_t *cc = nr_mac->common_channels; - //NR_ServingCellConfigCommon_t *scc=cc->ServingCellConfigCommon; - nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; - nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[gNB_mac->TX_req[CC_id].Number_of_PDUs]; - - mac_rlc_status_resp_t rlc_status; - - NR_UE_info_t *UE_info = &gNB_mac->UE_info; - - if (UE_info->num_UEs ==0) return; - - unsigned char sdu_lcids[NB_RB_MAX] = {0}; - uint16_t sdu_lengths[NB_RB_MAX] = {0}; - uint16_t rnti = UE_info->rnti[UE_id]; - NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id]; - - uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES]; - - LOG_D(MAC, "Scheduling UE specific search space DCI type 1\n"); - - int ta_len = (ue_sched_ctl->ta_apply)?2:0; - - TBS_bytes = configure_fapi_dl_pdu_phytest( - module_idP, - dl_req, - pucch_sched, - dlsch_config != NULL ? dlsch_config->mcsIndex : NULL, - dlsch_config != NULL ? &dlsch_config->rbSize : NULL, - dlsch_config != NULL ? &dlsch_config->rbStart : NULL); - - if (TBS_bytes == 0) - return; - - lcid = DL_SCH_LCID_DTCH; - - //for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - - // TODO: check if the lcid is active - - LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n", - module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3); - - //if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { - rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - slotP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - 0, - 0); - - if (rlc_status.bytes_in_buffer > 0) { - - LOG_I(MAC, "configure fapi due to data availability \n"); - - LOG_I(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n", - module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, - lcid, header_length_total, TBS_bytes); - - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, - (char *)&mac_sdus[sdu_length_total], - 0, - 0); - - LOG_W(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid); - - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); - header_length_total += header_length_last; - - num_sdus++; - - //ue_sched_ctl->uplane_inactivity_timer = 0; - } - - else { - - LOG_D(MAC,"Configuring DL_TX in %d.%d\n", frameP, slotP); - - // fill dlsch_buffer with random data - for (i = 0; i < TBS_bytes; i++){ - mac_sdus[i] = (unsigned char) (lrand48()&0xff); - //((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff); - } - //Sending SDUs with size 1 - //Initialize elements of sdu_lcids and sdu_lengths - sdu_lcids[0] = 0x3f; // DRB - sdu_lengths[0] = TBS_bytes - ta_len - 3; - header_length_total += 2 + (sdu_lengths[0] >= 128); - sdu_length_total += sdu_lengths[0]; - num_sdus +=1; - - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - if (frameP%100 == 0){ - LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes); - for(int i = 0; i < 10; i++) { - LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[CC_id][0][0].payload[0])[i]); - } - } - #endif - - } - - UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total; - - // there is at least one SDU or TA command - // if (num_sdus > 0 ){ - if (ta_len + sdu_length_total + header_length_total > 0) { - - // Check if there is data from RLC or CE - if (TBS_bytes >= 2 + header_length_total + sdu_length_total + ta_len) { - // we have to consider padding - // padding param currently not in use - //padding = TBS_bytes - header_length_total - sdu_length_total - ta_len - 1; - post_padding = 1; - } else { - //padding = 0; - post_padding = 0; - } - - offset = nr_generate_dlsch_pdu(module_idP, - &UE_info->UE_sched_ctrl[UE_id], - (unsigned char *) mac_sdus, - (unsigned char *) gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0], - num_sdus, //num_sdus - sdu_lengths, - sdu_lcids, - 255, // no drx - NULL, // contention res id - post_padding); - - // Padding: fill remainder of DLSCH with 0 - if (post_padding > 0){ - for (int j = 0; j < (TBS_bytes - offset); j++) - gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0][offset + j] = 0; // mac_pdu[offset + j] = 0; - } - - configure_fapi_dl_Tx(module_idP, frameP, slotP, dl_req, tx_req, TBS_bytes, gNB_mac->pdu_index[CC_id]); - - if(IS_SOFTMODEM_NOS1){ - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n \n", frameP, slotP, TBS_bytes); - for(int i = 0; i < 10; i++) { // TBS_bytes dlsch_pdu_rel15->transport_block_size/8 6784/8 - LOG_I(MAC, "%x. ", mac_payload[i]); - } - #endif - } else { -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - if (frameP%100 == 0){ - LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes); - for(int i = 0; i < 10; i++) { - LOG_I(MAC, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]); - } - } -#endif - } - } - else { // There is no data from RLC or MAC header, so don't schedule - } - -} - int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) { uint8_t hrq_id; @@ -980,7 +619,7 @@ void schedule_fapi_ul_pdu(int Mod_idP, pusch_pdu->resource_alloc = 1; //type 1 pusch_pdu->rb_start = 0; if (get_softmodem_params()->phy_test==1) - pusch_pdu->rb_size = 50; + pusch_pdu->rb_size = min(pusch_pdu->bwp_size,50); else pusch_pdu->rb_size = pusch_pdu->bwp_size; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index a88a05b08b..dda70ef66a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -432,27 +432,17 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, } void nr_fill_nfapi_dl_pdu(int Mod_idP, - int UE_id, - int bwp_id, - NR_SearchSpace_t *ss, - NR_ControlResourceSet_t *coreset, nfapi_nr_dl_tti_request_body_t *dl_req, + rnti_t rnti, + NR_CellGroupConfig_t *secondaryCellGroup, + NR_UE_sched_ctrl_t *sched_ctrl, NR_sched_pucch *pucch_sched, - int nrOfLayers, - uint8_t mcs, - uint16_t rbSize, - uint16_t rbStart, - uint8_t numDmrsCdmGrpsNoData, nfapi_nr_dmrs_type_e dmrsConfigType, - uint8_t table_idx, uint16_t R, uint8_t Qm, uint32_t TBS, - int time_domain_assignment, int StartSymbolIndex, int NrOfSymbols, - uint8_t aggregation_level, - int CCEIndex, int harq_pid, int ndi, int round) { @@ -460,9 +450,10 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP, NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + const int bwp_id = sched_ctrl->active_bwp->bwp_Id; + const int nrOfLayers = 1; + const int mcs = sched_ctrl->mcs; - NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); @@ -487,7 +478,7 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP, pdsch_pdu_rel15->pduBitmap = 0; - pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id]; + pdsch_pdu_rel15->rnti = rnti; pdsch_pdu_rel15->pduIndex = nr_mac->pdu_index[0]++; // BWP @@ -512,20 +503,19 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP, pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; - pdsch_pdu_rel15->numDmrsCdmGrpsNoData = numDmrsCdmGrpsNoData; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData; pdsch_pdu_rel15->dmrsPorts = 1; pdsch_pdu_rel15->resourceAlloc = 1; - pdsch_pdu_rel15->rbStart = rbStart; - pdsch_pdu_rel15->rbSize = rbSize; + pdsch_pdu_rel15->rbStart = sched_ctrl->rbStart; + pdsch_pdu_rel15->rbSize = sched_ctrl->rbSize; pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP pdsch_pdu_rel15->targetCodeRate[0] = R; pdsch_pdu_rel15->qamModOrder[0] = Qm; pdsch_pdu_rel15->TBSize[0] = TBS; - pdsch_pdu_rel15->mcsTable[0] = table_idx; + pdsch_pdu_rel15->mcsTable[0] = sched_ctrl->mcsTableIdx; pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; - // k0 = *bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0; pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, @@ -550,8 +540,8 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP, 275)); else AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); - // time domain assignment - dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; // row index used here instead of SLIV; + // time domain assignment: row index used instead of SLIV + dci_pdu_rel15[0].time_domain_assignment.val = sched_ctrl->time_domain_allocation; // mcs and rv dci_pdu_rel15[0].mcs = mcs; dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0]; @@ -562,7 +552,7 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP, dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3; // TPC for PUCCH - dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213 + dci_pdu_rel15[0].tpc = sched_ctrl->tpc1; // table 7.2.1-1 in 38.213 // PUCCH resource indicator dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator; // PDSCH to HARQ TI @@ -587,18 +577,18 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP, nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, - UE_info->rnti[UE_id], - ss, - coreset, + rnti, + sched_ctrl->search_space, + sched_ctrl->coreset, scc, bwp, - aggregation_level, - CCEIndex); + sched_ctrl->aggregation_level, + sched_ctrl->cce_index); int dci_formats[2]; int rnti_types[2]; - if (ss->searchSpaceType->choice.ue_Specific->dci_Formats) + if (sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats) dci_formats[0] = NR_DL_DCI_FORMAT_1_1; else dci_formats[0] = NR_DL_DCI_FORMAT_1_0; @@ -618,17 +608,6 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP, pdcch_pdu_rel15->StartSymbolIndex, pdcch_pdu_rel15->DurationSymbols); - // I don't know why the following is not needed, but in this case we don't - // need additional calculations: - //const uint16_t N_RE_prime = NR_NB_SC_PER_RB * N_sh_symb - N_PRB_DMRS - N_PRB_oh; - //LOG_D(MAC, - // "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", - // N_RE_prime, - // N_sh_symb, - // N_PRB_DMRS, - // N_PRB_oh); - //pdsch_pdu_rel15->nb_mod_symbols = N_RE_prime*pdsch_pdu_rel15->n_prb*pdsch_pdu_rel15->nb_codewords; - LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d " "nb_layers %d nb_codewords %d mcs %d TBS: %d\n", @@ -735,10 +714,11 @@ void nr_configure_pdcch(gNB_MAC_INST *nr_mac, void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, NR_ServingCellConfigCommon_t *scc, NR_BWP_Uplink_t *bwp, + uint16_t rnti, uint8_t pucch_resource, - uint16_t O_uci, + uint16_t O_csi, uint16_t O_ack, - uint8_t SR_flag) { + uint8_t O_sr) { NR_PUCCH_Config_t *pucch_Config; NR_PUCCH_Resource_t *pucchres; @@ -753,6 +733,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, pucch_pdu->bit_len_harq = O_ack; + uint16_t O_uci = O_csi + O_ack; + if (bwp) { // This is not the InitialBWP NR_PUSCH_Config_t *pusch_Config = bwp->bwp_Dedicated->pusch_Config->choice.setup; @@ -815,7 +797,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, else AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci); } - else { + if (pucchresset->pucch_ResourceSetId == 1 && O_uci>2) { #if (NR_RRC_VERSION >= MAKE_VERSION(16, 0, 0)) N3 = pucchresset->maxPayloadSize!= NULL ? *pucchresset->maxPayloadSize : 1706; #else @@ -845,6 +827,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, if (pucchres->pucch_ResourceId == *resource_id) { res_found = 1; pucch_pdu->prb_start = pucchres->startingPRB; + pucch_pdu->rnti = rnti; // FIXME why there is only one frequency hopping flag // what about inter slot frequency hopping? pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping!= NULL ? 1 : 0; @@ -855,7 +838,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, pucch_pdu->initial_cyclic_shift = pucchres->format.choice.format0->initialCyclicShift; pucch_pdu->nr_of_symbols = pucchres->format.choice.format0->nrofSymbols; pucch_pdu->start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex; - pucch_pdu->sr_flag = SR_flag; + pucch_pdu->sr_flag = O_sr; break; case NR_PUCCH_Resource__format_PR_format1 : pucch_pdu->format_type = 1; @@ -863,21 +846,23 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, pucch_pdu->nr_of_symbols = pucchres->format.choice.format1->nrofSymbols; pucch_pdu->start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex; pucch_pdu->time_domain_occ_idx = pucchres->format.choice.format1->timeDomainOCC; - pucch_pdu->sr_flag = SR_flag; + pucch_pdu->sr_flag = O_sr; break; case NR_PUCCH_Resource__format_PR_format2 : pucch_pdu->format_type = 2; pucch_pdu->nr_of_symbols = pucchres->format.choice.format2->nrofSymbols; pucch_pdu->start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex; - pucch_pdu->prb_size = pucchres->format.choice.format2->nrofPRBs; pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId; pucch_pdu->dmrs_scrambling_id = id0!= NULL ? *id0 : *scc->physCellId; + pucch_pdu->prb_size = compute_pucch_prb_size(2,pucchres->format.choice.format2->nrofPRBs, + O_uci+O_sr,O_csi,pucch_Config->format2->choice.setup->maxCodeRate, + 2,pucchres->format.choice.format2->nrofSymbols,8); + pucch_pdu->bit_len_csi_part1 = O_csi; break; case NR_PUCCH_Resource__format_PR_format3 : pucch_pdu->format_type = 3; pucch_pdu->nr_of_symbols = pucchres->format.choice.format3->nrofSymbols; pucch_pdu->start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex; - pucch_pdu->prb_size = pucchres->format.choice.format3->nrofPRBs; pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId; if (pucch_Config->format3 == NULL) { pucch_pdu->pi_2bpsk = 0; @@ -888,6 +873,19 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ? 1 : 0; pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ? 1 : 0; } + int f3_dmrs_symbols; + if (pucchres->format.choice.format3->nrofSymbols==4) + f3_dmrs_symbols = 1<freq_hop_flag; + else { + if(pucchres->format.choice.format3->nrofSymbols<10) + f3_dmrs_symbols = 2; + else + f3_dmrs_symbols = 2<add_dmrs_flag; + } + pucch_pdu->prb_size = compute_pucch_prb_size(3,pucchres->format.choice.format3->nrofPRBs, + O_uci+O_sr,O_csi,pucch_Config->format3->choice.setup->maxCodeRate, + 2-pucch_pdu->pi_2bpsk,pucchres->format.choice.format3->nrofSymbols-f3_dmrs_symbols,12); + pucch_pdu->bit_len_csi_part1 = O_csi; break; case NR_PUCCH_Resource__format_PR_format4 : pucch_pdu->format_type = 4; @@ -905,6 +903,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, pucch_pdu->pi_2bpsk = pucchfmt->pi2BPSK!= NULL ? 1 : 0; pucch_pdu->add_dmrs_flag = pucchfmt->additionalDMRS!= NULL ? 1 : 0; } + pucch_pdu->bit_len_csi_part1 = O_csi; break; default : AssertFatal(1==0,"Undefined PUCCH format \n"); @@ -920,6 +919,84 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, } +uint16_t compute_pucch_prb_size(uint8_t format, + uint8_t nr_prbs, + uint16_t O_tot, + uint16_t O_csi, + NR_PUCCH_MaxCodeRate_t *maxCodeRate, + uint8_t Qm, + uint8_t n_symb, + uint8_t n_re_ctrl) { + + uint16_t O_crc; + + if (O_tot<12) + O_crc = 0; + else{ + if (O_tot<20) + O_crc = 6; + else { + if (O_tot<360) + O_crc = 11; + else + AssertFatal(1==0,"Case for segmented PUCCH not yet implemented"); + } + } + + int rtimes100; + switch(*maxCodeRate){ + case NR_PUCCH_MaxCodeRate_zeroDot08 : + rtimes100 = 8; + break; + case NR_PUCCH_MaxCodeRate_zeroDot15 : + rtimes100 = 15; + break; + case NR_PUCCH_MaxCodeRate_zeroDot25 : + rtimes100 = 25; + break; + case NR_PUCCH_MaxCodeRate_zeroDot35 : + rtimes100 = 35; + break; + case NR_PUCCH_MaxCodeRate_zeroDot45 : + rtimes100 = 45; + break; + case NR_PUCCH_MaxCodeRate_zeroDot60 : + rtimes100 = 60; + break; + case NR_PUCCH_MaxCodeRate_zeroDot80 : + rtimes100 = 80; + break; + default : + AssertFatal(1==0,"Invalid MaxCodeRate"); + } + + float r = (float)rtimes100/100; + + if (O_csi == O_tot) { + if ((O_tot+O_csi)>(nr_prbs*n_re_ctrl*n_symb*Qm*r)) + AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with %d PRBs", + r,O_tot,O_crc,nr_prbs); + else + return nr_prbs; + } + + if (format==2){ + // TODO fix this for multiple CSI reports + for (int i=1; i<=nr_prbs; i++){ + if((O_tot+O_crc)<=(i*n_symb*Qm*n_re_ctrl*r) && + (O_tot+O_crc)>((i-1)*n_symb*Qm*n_re_ctrl*r)) + return i; + } + AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with at most %d PRBs", + r,O_tot,O_crc,nr_prbs); + } + else{ + AssertFatal(1==0,"Not yet implemented"); + } + +} + + void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup, dci_pdu_rel15_t *dci_pdu_rel15, nr_dci_format_t format, @@ -1612,6 +1689,20 @@ inline void add_nr_ue_list(NR_UE_list_t *listP, int UE_id) { *cur = UE_id; } +/* + * Remove a UE from NR_UE_list listP + */ +static inline void remove_nr_ue_list(NR_UE_list_t *listP, int UE_id) { + int *cur = &listP->head; + while (*cur != -1 && *cur != UE_id) + cur = &listP->next[*cur]; + AssertFatal(*cur != -1, "UE %d not found in UE_list\n", UE_id); + int *next = &listP->next[*cur]; + *cur = listP->next[*cur]; + *next = -1; + return; +} + int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP) //------------------------------------------------------------------------------ { @@ -1690,15 +1781,21 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ memset((void *) &UE_info->UE_sched_ctrl[UE_id], 0, sizeof(NR_UE_sched_ctrl_t)); - UE_info->UE_sched_ctrl[UE_id].ta_timer = 100; + UE_info->UE_sched_ctrl[UE_id].ta_frame = 0; UE_info->UE_sched_ctrl[UE_id].ta_update = 31; + UE_info->UE_sched_ctrl[UE_id].ta_apply = false; UE_info->UE_sched_ctrl[UE_id].ul_rssi = 0; - UE_info->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch)); + UE_info->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch **)malloc(num_slots_ul*sizeof(NR_sched_pucch *)); + for (int s=0; sUE_sched_ctrl[UE_id].sched_pucch[s] = (NR_sched_pucch *)malloc(2*sizeof(NR_sched_pucch)); UE_info->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch)); + for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k], - 0, - sizeof(NR_sched_pucch)); + for (int l=0; l<2; l++) + memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l], + 0, + sizeof(NR_sched_pucch)); + memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k], 0, sizeof(NR_sched_pusch)); @@ -1737,9 +1834,11 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti) /* UE found, remove it */ UE_id = i; + UE_info->num_UEs--; UE_info->active[UE_id] = FALSE; UE_info->rnti[UE_id] = 0; + remove_nr_ue_list(&UE_info->list, UE_id); free(UE_info->UE_sched_ctrl[UE_id].sched_pucch); free(UE_info->UE_sched_ctrl[UE_id].sched_pusch); memset((void *) &UE_info->UE_sched_ctrl[UE_id], @@ -1821,50 +1920,302 @@ void get_pdsch_to_harq_feedback(int Mod_idP, } } + +uint16_t nr_get_csi_bitlen(int Mod_idP, + int UE_id, + uint8_t csi_report_id) { + + uint16_t csi_bitlen =0; + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + CRI_SSBRI_RSRP_bitlen_t * CSI_report_bitlen = NULL; + + CSI_report_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0]); + csi_bitlen = ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) + + CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen * + (CSI_report_bitlen->nb_ssbri_cri -1 )) *UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report); + + return csi_bitlen; +} + + +void csi_period_offset(NR_CSI_ReportConfig_t *csirep, + int *period, int *offset) { + + NR_CSI_ReportPeriodicityAndOffset_PR p_and_o = csirep->reportConfigType.choice.periodic->reportSlotConfig.present; + + switch(p_and_o){ + case NR_CSI_ReportPeriodicityAndOffset_PR_slots4: + *period = 4; + *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots4; + break; + case NR_CSI_ReportPeriodicityAndOffset_PR_slots5: + *period = 5; + *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots5; + break; + case NR_CSI_ReportPeriodicityAndOffset_PR_slots8: + *period = 8; + *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots8; + break; + case NR_CSI_ReportPeriodicityAndOffset_PR_slots10: + *period = 10; + *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots10; + break; + case NR_CSI_ReportPeriodicityAndOffset_PR_slots16: + *period = 16; + *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots16; + break; + case NR_CSI_ReportPeriodicityAndOffset_PR_slots20: + *period = 20; + *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots20; + break; + case NR_CSI_ReportPeriodicityAndOffset_PR_slots40: + *period = 40; + *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots40; + break; + case NR_CSI_ReportPeriodicityAndOffset_PR_slots80: + *period = 80; + *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots80; + break; + case NR_CSI_ReportPeriodicityAndOffset_PR_slots160: + *period = 160; + *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots160; + break; + case NR_CSI_ReportPeriodicityAndOffset_PR_slots320: + *period = 320; + *offset = csirep->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320; + break; + default: + AssertFatal(1==0,"No periodicity and offset resource found in CSI report"); + } +} + + +//!TODO : same function can be written to handle csi_resources +void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t *UE_info, int UE_id) { + uint8_t csi_report_id = 0; + uint8_t csi_resourceidx =0; + uint8_t csi_ssb_idx =0; + + NR_CSI_MeasConfig_t *csi_MeasConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + NR_CSI_ResourceConfigId_t csi_ResourceConfigId; + for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ + csi_ResourceConfigId=csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->resourcesForChannelMeasurement; + UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->reportQuantity.present; + + for ( csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) { + if ( csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_ResourceConfigId != csi_ResourceConfigId) + continue; + else { + //Finding the CSI_RS or SSB Resources + UE_info->csi_report_template[UE_id][csi_report_id].CSI_Resource_type= csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.present; + if (NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB ==UE_info->csi_report_template[UE_id][csi_report_id].CSI_Resource_type){ + struct NR_CSI_ResourceConfig__csi_RS_ResourceSetList__nzp_CSI_RS_SSB * nzp_CSI_RS_SSB = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB; + + UE_info->csi_report_template[UE_id][csi_report_id].nb_of_nzp_csi_report = nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.count:0; + UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report = nzp_CSI_RS_SSB->csi_SSB_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.count:0; + } + + if (0 != UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report){ + uint8_t nb_ssb_resources =0; + for ( csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) { + if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId == + *(csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])) { ///We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig + if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == + csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.present ) { + if (NULL != csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.choice.disabled->nrofReportedRS) + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri = *(csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1; + else + /*! From Spec 38.331 + * nrofReportedRS + * The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE + * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report. + * When the field is absent the UE applies the value 1 + */ + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri= 1; + }else + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].nb_ssbri_cri= 2; + + nb_ssb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.count; + if (nb_ssb_resources){ + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen =ceil(log2 (nb_ssb_resources)); + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP + } + else{ + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen =0; + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen = 0; + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =0; + } + + LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d", + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen, + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen, + UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen); + break ; + } + } + } + if (0 != UE_info->csi_report_template[UE_id][csi_report_id].nb_of_nzp_csi_report){ + AssertFatal(1==0,"Currently configuring only SSB beamreporting."); + } + break; + } + } + } +} + +void nr_csi_meas_reporting(int Mod_idP, + int UE_id, + frame_t frame, + sub_frame_t slot, + int slots_per_tdd, + int ul_slots, + int n_slots_frame) { + + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + NR_sched_pucch *curr_pucch; + NR_PUCCH_ResourceSet_t *pucchresset; + NR_CSI_ReportConfig_t *csirep; + NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; + NR_CSI_MeasConfig_t *csi_measconfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]; + NR_PUCCH_Config_t *pucch_Config = ubwp->bwp_Dedicated->pucch_Config->choice.setup; + + AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count>0,"NO CSI report configuration available"); + + for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ + + csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; + + AssertFatal(csirep->reportConfigType.choice.periodic!=NULL,"Only periodic CSI reporting is implemented currently"); + int period, offset, sched_slot; + csi_period_offset(csirep,&period,&offset); + sched_slot = (period+offset)%n_slots_frame; + // prepare to schedule csi measurement reception according to 5.2.1.4 in 38.214 + // preparation is done in first slot of tdd period + if ( (frame%(period/n_slots_frame)==(offset/n_slots_frame)) && (slot==((sched_slot/slots_per_tdd)*slots_per_tdd))) { + + // we are scheduling pucch for csi in the first pucch occasion (this comes before ack/nack) + curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[sched_slot-slots_per_tdd+ul_slots][0]; + + NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0]; + + int found = -1; + pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1 + int n_list = pucchresset->resourceList.list.count; + for (int i=0; iresourceList.list.array[i] == pucchcsires->pucch_Resource) + found = i; + } + AssertFatal(found>-1,"CSI resource not found among PUCCH resources"); + + curr_pucch->resource_indicator = found; + + n_list = pucch_Config->resourceToAddModList->list.count; + + // going through the list of PUCCH resources to find the one indexed by resource_id + for (int i=0; iresourceToAddModList->list.array[i]; + if (pucchres->pucch_ResourceId == *pucchresset->resourceList.list.array[found]) { + switch(pucchres->format.present){ + case NR_PUCCH_Resource__format_PR_format2: + if (pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI == NULL) + curr_pucch->simultaneous_harqcsi = false; + else + curr_pucch->simultaneous_harqcsi = true; + break; + case NR_PUCCH_Resource__format_PR_format3: + if (pucch_Config->format3->choice.setup->simultaneousHARQ_ACK_CSI == NULL) + curr_pucch->simultaneous_harqcsi = false; + else + curr_pucch->simultaneous_harqcsi = true; + break; + case NR_PUCCH_Resource__format_PR_format4: + if (pucch_Config->format4->choice.setup->simultaneousHARQ_ACK_CSI == NULL) + curr_pucch->simultaneous_harqcsi = false; + else + curr_pucch->simultaneous_harqcsi = true; + break; + default: + AssertFatal(1==0,"Invalid PUCCH format type"); + } + } + } + curr_pucch->csi_bits += nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id); // TODO function to compute CSI meas report bit size + curr_pucch->frame = frame; + curr_pucch->ul_slot = sched_slot; + } + } +} + + // function to update pucch scheduling parameters in UE list when a USS DL is scheduled -void nr_update_pucch_scheduling(int Mod_idP, - int UE_id, - frame_t frameP, - sub_frame_t slotP, - int slots_per_tdd, - int *pucch_id) { +void nr_acknack_scheduling(int Mod_idP, + int UE_id, + frame_t frameP, + sub_frame_t slotP, + int slots_per_tdd, + int *pucch_id, + int *pucch_occ) { NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; NR_sched_pucch *curr_pucch; - int first_ul_slot_tdd,k,i; + int max_acknacks,pucch_res,first_ul_slot_tdd,k,i,l; uint8_t pdsch_to_harq_feedback[8]; int found = 0; int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0) nr_ulmix_slots++; + bool csi_pres=false; + for (k=0; kUE_sched_ctrl[UE_id].sched_pucch[k][0].csi_bits>0) + csi_pres=true; + } + + // As a preference always schedule ack nacks in PUCCH0 (max 2 per slots) + // Unless there is CSI meas reporting scheduled in the period to avoid conflicts in the same slot + if (csi_pres) + max_acknacks=10; + else + max_acknacks=2; + // this is hardcoded for now as ue specific NR_SearchSpace__searchSpaceType_PR ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific; get_pdsch_to_harq_feedback(Mod_idP,UE_id,ss_type,pdsch_to_harq_feedback); // for each possible ul or mixed slot for (k=0; kUE_sched_ctrl[UE_id].sched_pucch[k]; - // if there is free room in current pucch structure - if (curr_pucch->dai_cframe = frameP; - curr_pucch->dai_c++; - curr_pucch->resource_indicator = 0; // in phytest with only 1 UE we are using just the 1st resource - // first pucch occasion in first UL or MIXED slot - first_ul_slot_tdd = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; - i = 0; - while (i<8 && found == 0) { // look if timing indicator is among allowed values - if (pdsch_to_harq_feedback[i]==(first_ul_slot_tdd+k)-(slotP % slots_per_tdd)) - found = 1; - if (found == 0) i++; - } - if (found == 1) { - // computing slot in which pucch is scheduled - curr_pucch->ul_slot = first_ul_slot_tdd + k + (slotP - (slotP % slots_per_tdd)); - curr_pucch->timing_indicator = i; // index in the list of timing indicators - *pucch_id = k; - return; + for (l=0; l<1; l++) { // scheduling 2 PUCCH in a single slot does not work with the phone, currently + curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l]; + //if it is possible to schedule acknack in current pucch (no exclusive csi pucch) + if ((curr_pucch->csi_bits == 0) || (curr_pucch->simultaneous_harqcsi==true)) { + // if there is free room in current pucch structure + if (curr_pucch->dai_c-1){ + curr_pucch->resource_indicator = pucch_res; + curr_pucch->frame = frameP; + // first pucch occasion in first UL or MIXED slot + first_ul_slot_tdd = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; + i = 0; + while (i<8 && found == 0) { // look if timing indicator is among allowed values + if (pdsch_to_harq_feedback[i]==(first_ul_slot_tdd+k)-(slotP % slots_per_tdd)) + found = 1; + if (found == 0) i++; + } + if (found == 1) { + // computing slot in which pucch is scheduled + curr_pucch->dai_c++; + curr_pucch->ul_slot = first_ul_slot_tdd + k + (slotP - (slotP % slots_per_tdd)); + curr_pucch->timing_indicator = i; // index in the list of timing indicators + *pucch_id = k; + *pucch_occ = l; + return; + } + } + } } } } @@ -1872,6 +2223,22 @@ void nr_update_pucch_scheduling(int Mod_idP, } +int get_pucch_resource(NR_UE_info_t *UE_info,int UE_id,int k,int l) { + + // to be updated later, for now simple implementation + // use the second allocation just in case there is csi in the first + // in that case use second resource (for a different symbol) see 9.2 in 38.213 + if (l==1) { + if (UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][0].csi_bits==0) + return -1; + else + return 1; + } + else + return 0; + +} + void find_aggregation_candidates(uint8_t *aggregation_level, uint8_t *nr_of_candidates, NR_SearchSpace_t *ss) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 0479c4da30..84ad51f072 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -214,12 +214,8 @@ void nr_process_mac_pdu( int UE_id = find_nr_UE_id(module_idP, rnti); RC.nrmac[module_idP]->UE_info.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len; #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); + log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n"); - for (i = 0; i < 32; i++) - LOG_T(MAC, "%x.", (pdu_ptr + mac_subheader_len)[i]); - - LOG_T(MAC, "\n"); #endif if(IS_SOFTMODEM_NOS1){ mac_rlc_data_ind(module_idP, @@ -322,40 +318,10 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, UE_info = &gNB_mac->UE_info; int target_snrx10 = gNB_mac->pusch_target_snrx10; - NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[0]; - - // random access pusch with TC-RNTI - if (ra->state == WAIT_Msg3) { - if (sduP != NULL) { // if the CRC passed - - if (ra->rnti != current_rnti) { - LOG_E(MAC, - "expected TC-RNTI %04x to match current RNTI %04x\n", - ra->rnti, - current_rnti); - return; - } - free(ra->preambles.preamble_list); - ra->state = RA_IDLE; - LOG_I(MAC, "reset RA state information for RA-RNTI %04x\n", ra->rnti); - const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti); - UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup; - UE_info->UE_beam_index[UE_id] = ra->beam_id; - struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList; - AssertFatal(bwpList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", - bwpList->list.count); - const int bwp_id = 1; - UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1]; - LOG_I(MAC, - "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, " - "adding UE MAC Context UE_id %d/RNTI %04x\n", - gnb_mod_idP, - current_rnti, - UE_id, - ra->rnti); - } - return; + if (sduP != NULL) { + T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP), + T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */, + T_BUFFER(sduP, sdu_lenP)); } if (UE_id != -1) { @@ -385,6 +351,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n"); for (int i = 0; i < sdu_lenP ; i++) { //harq_process_ul_ue->a[i] = (unsigned char) rand(); @@ -392,6 +359,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, printf("%02x ",(unsigned char)sduP[i]); } printf("\n"); + #endif if (sduP != NULL){ @@ -401,6 +369,54 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, else { } - } -} + } else { + if (!sduP) // check that CRC passed + return; + /* we don't know this UE (yet). Check whether there is a ongoing RA (Msg 3) + * and check the corresponding UE's RNTI match, in which case we activate + * it. */ + for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) { + NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i]; + if (ra->state != WAIT_Msg3) + continue; + + // random access pusch with TC-RNTI + if (ra->rnti != current_rnti) { + LOG_W(MAC, + "expected TC-RNTI %04x to match current RNTI %04x\n", + ra->rnti, + current_rnti); + continue; + } + const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti); + UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup; + compute_csi_bitlen(ra->secondaryCellGroup, UE_info, UE_id); + UE_info->UE_beam_index[UE_id] = ra->beam_id; + struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList; + AssertFatal(bwpList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + bwpList->list.count); + const int bwp_id = 1; + UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1]; + LOG_I(MAC, + "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, " + "adding UE MAC Context UE_id %d/RNTI %04x\n", + gnb_mod_idP, + current_rnti, + UE_id, + ra->rnti); + // re-initialize ta update variables afrer RA procedure completion + UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP; + + free(ra->preambles.preamble_list); + ra->state = RA_IDLE; + LOG_I(MAC, + "reset RA state information for RA-RNTI %04x/index %d\n", + ra->rnti, + i); + return; + } + } + +} diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index f7e62c9755..b3cd91fd01 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -36,8 +36,6 @@ #include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include "NR_TAG-Id.h" -#define MAX_ACK_BITS 2 //only format 0 is available for now - void set_cset_offset(uint16_t); void mac_top_init_gNB(void); @@ -82,7 +80,13 @@ void nr_schedule_ue_spec(module_id_t module_id, sub_frame_t slot, int num_slots_per_tdd); -void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); +/* \brief default preprocessor */ +void nr_simple_dlsch_preprocessor(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd); + +void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, uint8_t slots_per_frame); /////// Random Access MAC-PHY interface functions and primitives /////// @@ -126,42 +130,37 @@ uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs); /////// Phy test scheduler /////// +/* \brief preprocessor for phytest: schedules UE_id 0 with fixed MCS on all + * freq resources */ +void nr_preprocessor_phytest(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd); + void nr_schedule_css_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); void nr_fill_nfapi_dl_pdu(int Mod_id, - int UE_id, - int bwp_id, - NR_SearchSpace_t *ss, - NR_ControlResourceSet_t *coreset, nfapi_nr_dl_tti_request_body_t *dl_req, + rnti_t rnti, + NR_CellGroupConfig_t *secondaryCellGroup, + NR_UE_sched_ctrl_t *sched_ctrl, NR_sched_pucch *pucch_sched, - int nrOfLayers, - uint8_t mcs, - uint16_t rbSize, - uint16_t rbStart, - uint8_t numDmrsCdmGrpsNoData, nfapi_nr_dmrs_type_e dmrsConfigType, - uint8_t table_idx, uint16_t R, uint8_t Qm, uint32_t tbs, - int time_domain_assignment, int StartSymbolIndex, int NrOfSymbols, - uint8_t aggregation_level, - int CCEIndex, int harq_pid, int ndi, int round); -int configure_fapi_dl_pdu_phytest(int Mod_id, - nfapi_nr_dl_tti_request_body_t *dl_req, - NR_sched_pucch *pucch_sched, - uint8_t *mcsIndex, - uint16_t *rbSize, - uint16_t *rbStart); +void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch, + nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01, + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234, + NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats); void config_uldci(NR_BWP_Uplink_t *ubwp, nfapi_nr_pusch_pdu_t *pusch_pdu, @@ -171,20 +170,6 @@ void config_uldci(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, uint8_t tpc, int n_ubwp, int bwp_id); -void configure_fapi_dl_Tx(module_id_t Mod_idP, - frame_t frameP, - sub_frame_t slotP, - nfapi_nr_dl_tti_request_body_t *dl_req, - nfapi_nr_pdu_t *tx_req, - int tbs_bytes, - int16_t pdu_index); - -void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, - frame_t frameP, - sub_frame_t slotP, - NR_sched_pucch *pucch_sched, - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_config); - void nr_schedule_pusch(int Mod_idP, int UE_id, int num_slots_per_tdd, @@ -198,12 +183,23 @@ void nr_schedule_pucch(int Mod_idP, frame_t frameP, sub_frame_t slotP); -void nr_update_pucch_scheduling(int Mod_idP, - int UE_id, - frame_t frameP, - sub_frame_t slotP, - int slots_per_tdd, - int *pucch_id); +void nr_csi_meas_reporting(int Mod_idP, + int UE_id, + frame_t frameP, + sub_frame_t slotP, + int slots_per_tdd, + int ul_slots, + int n_slots_frame); + +void nr_acknack_scheduling(int Mod_idP, + int UE_id, + frame_t frameP, + sub_frame_t slotP, + int slots_per_tdd, + int *pucch_id, + int *pucch_occ); + +int get_pucch_resource(NR_UE_info_t *UE_info,int UE_id,int k,int l); void get_pdsch_to_harq_feedback(int Mod_idP, int UE_id, @@ -232,10 +228,11 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space, void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, NR_ServingCellConfigCommon_t *scc, NR_BWP_Uplink_t *bwp, + uint16_t rnti, uint8_t pucch_resource, - uint16_t O_uci, + uint16_t O_csi, uint16_t O_ack, - uint8_t SR_flag); + uint8_t O_sr); void find_search_space(int ss_type, NR_BWP_Downlink_t *bwp, @@ -320,14 +317,23 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, int m, int nr_of_candidates); +uint16_t compute_pucch_prb_size(uint8_t format, + uint8_t nr_prbs, + uint16_t O_tot, + uint16_t O_csi, + NR_PUCCH_MaxCodeRate_t *maxCodeRate, + uint8_t Qm, + uint8_t n_symb, + uint8_t n_re_ctrl); + +void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t *UE_info, int UE_id); + int get_dlscs(nfapi_nr_config_request_t *cfg); int get_ulscs(nfapi_nr_config_request_t *cfg); int get_symbolsperslot(nfapi_nr_config_request_t *cfg); -int32_t get_nr_uldl_offset(int nr_bandP); - void config_nr_mib(int Mod_idP, int CC_idP, int p_gNBP, @@ -366,6 +372,8 @@ int binomial(int n, int k); bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot); +void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id); + /* \brief Function to indicate a received SDU on ULSCH. @param Mod_id Instance ID of gNB diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 7df00f15f1..b7db1f67aa 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -82,6 +82,11 @@ void mac_top_init_gNB(void) RC.nrmac[i]->ul_handle = 0; + if (get_softmodem_params()->phy_test) + RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest; + else + RC.nrmac[i]->pre_processor_dl = nr_simple_dlsch_preprocessor; + }//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++) AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n"); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index f6fdea064c..656d1c3e7c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -68,6 +68,9 @@ #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" #include "NR_TAG.h" +#include + + /* Defs */ #define MAX_NUM_BWP 2 #define MAX_NUM_CORESET 2 @@ -188,9 +191,9 @@ typedef struct { /// Template for RA computations NR_RA_t ra[NR_NB_RA_PROC_MAX]; /// VRB map for common channels - uint8_t vrb_map[275]; + uint16_t vrb_map[275]; /// VRB map for common channels and retransmissions by PHICH - uint8_t vrb_map_UL[275]; + uint16_t vrb_map_UL[275]; /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; ///Number of active SSBs @@ -274,10 +277,12 @@ typedef struct UE_info { typedef struct NR_sched_pucch { int frame; int ul_slot; + bool sr_flag; + int csi_bits; + bool simultaneous_harqcsi; uint8_t dai_c; uint8_t timing_indicator; uint8_t resource_indicator; - bool active; } NR_sched_pucch; typedef struct NR_sched_pusch { @@ -315,6 +320,25 @@ typedef struct NR_UE_ul_harq { NR_UL_harq_states_t state; } NR_UE_ul_harq_t; + +typedef struct { + uint8_t nb_ssbri_cri; + uint8_t cri_ssbri_bitlen; + uint8_t rsrp_bitlen; + uint8_t diff_rsrp_bitlen; +}CRI_SSBRI_RSRP_bitlen_t; + + +#define MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG 16 +typedef struct nr_csi_report { + NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; + NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR CSI_Resource_type; + uint8_t nb_of_nzp_csi_report; + uint8_t nb_of_csi_ssb_report; + CRI_SSBRI_RSRP_bitlen_t CSI_report_bitlen[MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG]; +} nr_csi_report_t; + + /*! \brief scheduling control information set through an API */ typedef struct { /// total amount of data awaiting for this UE @@ -324,9 +348,10 @@ typedef struct { /// the currently active BWP in DL NR_BWP_Downlink_t *active_bwp; - NR_sched_pucch *sched_pucch; + NR_sched_pucch **sched_pucch; /// selected PUCCH index, if scheduled int pucch_sched_idx; + int pucch_occ_idx; NR_sched_pusch *sched_pusch; /// CCE index and aggregation, should be coherent with cce_list @@ -350,7 +375,7 @@ typedef struct { /// Retransmission-related information NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES]; - uint16_t ta_timer; + uint16_t ta_frame; int16_t ta_update; bool ta_apply; uint8_t tpc0; @@ -364,7 +389,11 @@ typedef struct { } NR_UE_sched_ctrl_t; typedef struct { + boolean_t fiveG_connected; + uicc_t *uicc; +} NRUEcontext_t; +typedef struct { int lc_bytes_tx[64]; int lc_bytes_rx[64]; int dlsch_rounds[8]; @@ -377,6 +406,7 @@ typedef struct { } NR_mac_stats_t; + /*! \brief UNR_E_list_t is a "list" of users within UE_info_t. Especial useful in * the scheduler and to keep "classes" of users. */ typedef struct { @@ -384,14 +414,18 @@ typedef struct { int next[MAX_MOBILES_PER_GNB]; } NR_UE_list_t; + /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ +#define MAX_CSI_REPORTCONFIG 48 typedef struct { DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB]; /// scheduling control info + nr_csi_report_t csi_report_template[MAX_MOBILES_PER_GNB][MAX_CSI_REPORTCONFIG]; NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB]; NR_UE_list_t list; int num_UEs; + bool active[MAX_MOBILES_PER_GNB]; rnti_t rnti[MAX_MOBILES_PER_GNB]; NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB]; @@ -403,6 +437,11 @@ typedef struct { uint8_t UE_beam_index[MAX_MOBILES_PER_GNB]; } NR_UE_info_t; +typedef void (*nr_pp_impl_dl)(module_id_t mod_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd); + /*! \brief top level eNB MAC structure */ typedef struct gNB_MAC_INST_s { /// Ethernet parameters for northbound midhaul interface @@ -465,6 +504,9 @@ typedef struct gNB_MAC_INST_s { int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE]; /// current slot int current_slot; + + /// DL preprocessor for differentiated scheduling + nr_pp_impl_dl pre_processor_dl; } gNB_MAC_INST; #endif /*__LAYER2_NR_MAC_GNB_H__ */ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 33f268f07f..12ad6bf6a2 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -996,17 +996,7 @@ pdcp_data_ind( * TODO: be sure of this */ if (NFAPI_MODE == NFAPI_UE_STUB_PNF ) { -#ifdef UESIM_EXPANSION - - if (UE_NAS_USE_TUN) { - pdcpHead->inst = ctxt_pP->module_id; - } else { - pdcpHead->inst = 0; - } - -#else pdcpHead->inst = ctxt_pP->module_id; -#endif } else { // nfapi_mode if (UE_NAS_USE_TUN) { pdcpHead->inst = ctxt_pP->module_id; @@ -1035,7 +1025,7 @@ pdcp_data_ind( pushNotifiedFIFO(&pdcp_sdu_list, new_sdu_p); /* Print octets of incoming data in hexadecimal form */ - LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", + LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), sdu_buffer_sizeP - payload_offset); //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); @@ -2287,7 +2277,7 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { nas_getparams(); if(UE_NAS_USE_TUN) { - int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1; + int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1; netlink_init_tun("ue",num_if); if (IS_SOFTMODEM_NOS1) nas_config(1, 1, 2, "ue"); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index de8a1b385b..c8ab4499ee 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -53,9 +53,6 @@ typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *cons typedef boolean_t (*pdcp_data_ind_func_t)( const protocol_ctxt_t *, const srb_flag_t, const MBMS_flag_t, const rb_id_t, const sdu_size_t, mem_block_t *,const uint32_t *const, const uint32_t *const); -/* maximum number of tun interfaces that will be created to emulates UEs */ -/* UEs beyond that will be multiplexed on the same tun */ -#define MAX_NUMBER_NETIF 16 #define ENB_NAS_USE_TUN_W_MBMS_BIT (1<< 10) #define PDCP_USE_NETLINK_BIT (1<< 11) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index c9a62d573b..04b9e188e6 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -86,12 +86,6 @@ extern struct msghdr nas_msg_rx; -#ifdef UESIM_EXPANSION - extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; -#endif - - - # include "gtpv1u_eNB_task.h" # include "gtpv1u_eNB_defs.h" @@ -156,9 +150,9 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { nas_nlh_tx->nlmsg_len = sizeToWrite; ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0); } // PDCP_USE_NETLINK - - AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]); + AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]); + if( LOG_DEBUGFLAG(DEBUG_PDCP) ) log_dump(PDCP, pdcpData, min(sizeToWrite,30) , LOG_DUMP_CHAR, "Printing first bytes of PDCP SDU before removing it from the list: \n"); @@ -202,6 +196,7 @@ int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) { //} // PDCP_USE_NETLINK //AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno)); + //AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno)); delNotifiedFIFO_elt (sdu_p); pdcp_nb_sdu_sent ++; @@ -503,11 +498,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx } } else { // ctxt.enb_flag => UE if (NFAPI_MODE == NFAPI_UE_STUB_PNF) { -#ifdef UESIM_EXPANSION - ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst]; -#else ctxt.module_id = pdcp_read_header_g.inst; -#endif } else { ctxt.module_id = 0; } diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 27ca18ed7e..7e4920a579 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -143,7 +143,7 @@ void (*rlc_rrc_data_conf)( const protocol_ctxt_t *const ctxtP, const rb_id_t rb_idP, const mui_t muiP, - const rlc_tx_status_t statusP); + const rlc_tx_status_t statusP) __attribute__ ((aligned(32))); typedef void (rrc_data_ind_cb_t)( const protocol_ctxt_t *const ctxtP, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 38b81e7aff..ca37026e54 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -19,6 +19,9 @@ * contact@openairinterface.org */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include "nr_pdcp_ue_manager.h" #include "NR_RadioBearerConfig.h" #include "NR_RLC-BearerConfig.h" @@ -43,6 +46,7 @@ static uint64_t pdcp_optmask; /* rlc_data_req queue - begin */ /****************************************************************************/ + #include /* NR PDCP and RLC both use "big locks". In some cases a thread may do @@ -92,6 +96,7 @@ static void *rlc_data_req_thread(void *_) { int i; + pthread_setname_np(pthread_self(), "RLC queue"); while (1) { if (pthread_mutex_lock(&q.m) != 0) abort(); while (q.length == 0) @@ -203,6 +208,7 @@ static void *enb_tun_read_thread(void *_) protocol_ctxt_t ctxt; int rb_id = 1; + pthread_setname_np( pthread_self(),"enb_tun_read"); while (1) { len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD); @@ -247,7 +253,7 @@ static void *ue_tun_read_thread(void *_) protocol_ctxt_t ctxt; int rb_id = 1; - + pthread_setname_np( pthread_self(),"ue_tun_read"); while (1) { len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD); if (len == -1) { @@ -368,7 +374,7 @@ uint64_t pdcp_module_init(uint64_t _pdcp_optmask) nas_getparams(); if(UE_NAS_USE_TUN) { - int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1; + int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1; netlink_init_tun("ue",num_if); //Add --nr-ip-over-lte option check for next line if (IS_SOFTMODEM_NOS1) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index 78a49e4604..804f1e8a74 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -922,6 +922,7 @@ static missing_data_t next_missing(nr_rlc_entity_am_t *entity, */ ret.sn_start = entity->rx_next; ret.so_start = 0; + ret.next = cur; goto set_end_different_sdu; } } @@ -1284,7 +1285,7 @@ static int missing_size(nr_rlc_entity_am_t *entity, missing_data_t *m, missing_data_t m_nack; /* be careful to limit a range to 255 SNs, that is: cut if needed */ - sn_count = m->sn_end - m->sn_start; + sn_count = m->sn_end - m->sn_start + 1; if (sn_count < 0) sn_count += entity->sn_modulus; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 5048dd245e..3a46f913e9 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -917,6 +917,9 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) void nr_rlc_tick(int frame, int subframe) { if (frame != nr_rlc_current_time_last_frame || - subframe != nr_rlc_current_time_last_subframe) + subframe != nr_rlc_current_time_last_subframe) { + nr_rlc_current_time_last_frame = frame; + nr_rlc_current_time_last_subframe = subframe; nr_rlc_current_time++; + } } diff --git a/openair2/LAYER2/nr_rlc/tests/run_tests.sh b/openair2/LAYER2/nr_rlc/tests/run_tests.sh index ac22516064..bf1b343d7e 100755 --- a/openair2/LAYER2/nr_rlc/tests/run_tests.sh +++ b/openair2/LAYER2/nr_rlc/tests/run_tests.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_count=13 +test_count=14 for i in `seq $test_count` do diff --git a/openair2/LAYER2/nr_rlc/tests/test14.h b/openair2/LAYER2/nr_rlc/tests/test14.h new file mode 100644 index 0000000000..9eb472b270 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test14.h @@ -0,0 +1,46 @@ +/* + * am test (SN field size 18): + * test status reporting with missing packet + * at time 1, UE receives an SDU of 50 bytes + * at time 2, UE receives an SDU of 50 bytes + * at time 3, UE receives an SDU of 50 bytes + * at time 4, UE receives an SDU of 50 bytes + * transmission fails for first SDU, okay for the others + * then some time with transmission failing + * then at time 49, UE receives an SDU, transmission okay + * then at time 50, transmission failing again (we had a bug triggered by this) + * finally at time 55, transmission okay again to clear buffers + */ + +TIME, 1, + GNB_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18, + UE_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18, + GNB_RECV_FAILS, 1, + GNB_PDU_SIZE, 80, + UE_PDU_SIZE, 80, + UE_SDU, 0, 50, +TIME, 2, + GNB_RECV_FAILS, 0, + UE_SDU, 1, 50, +TIME, 3, + GNB_BUFFER_STATUS, + UE_SDU, 2, 50, +TIME, 4, + GNB_BUFFER_STATUS, + UE_SDU, 3, 50, +TIME, 5, + GNB_BUFFER_STATUS, + GNB_RECV_FAILS, 1, +TIME, 6, + GNB_BUFFER_STATUS, + UE_BUFFER_STATUS, +TIME, 49, + GNB_RECV_FAILS, 0, + UE_SDU, 4, 50, +TIME, 50, + GNB_RECV_FAILS, 1, + GNB_BUFFER_STATUS, + UE_BUFFER_STATUS, +TIME, 55, + GNB_RECV_FAILS, 0, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test14.txt.gz b/openair2/LAYER2/nr_rlc/tests/test14.txt.gz new file mode 100644 index 0000000000..7ab2fc3431 Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test14.txt.gz differ diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 86e00ef674..05118a5f6b 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -287,18 +287,6 @@ ue_ip_common_ip2wireless( printk("[UE_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, dst_addr[0],dst_addr[1],dst_addr[2],dst_addr[3]); } - // modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator start -#ifdef UESIM_EXPANSION - - if ((src_addr[3] - 2)> instP) { - pdcph.inst = src_addr[3] - 2; - printk("[UE_IP_DRV] change INST from %d to %d\n",instP, pdcph.inst); - instP = src_addr[3] - 2; - priv_p=netdev_priv(ue_ip_dev[instP]); - } - -#endif - // modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator end //get Ipv4 address and pass to PCDP header printk("[UE_IP_DRV] source Id: 0x%08x\n",pdcph.sourceL2Id ); printk("[UE_IP_DRV] destinationL2Id Id: 0x%08x\n",pdcph.destinationL2Id ); diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 22099c340a..4e1a8ae131 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -79,6 +79,44 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) { } +void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10) { + + int num_ucis = UL_info->uci_ind.num_ucis; + nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list; + + for (int i = 0; i < num_ucis; i++) { + switch (uci_list[i].pdu_type) { + case NFAPI_NR_UCI_PUSCH_PDU_TYPE: break; + + case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1; + + // tpc (power control) + sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30); + + if( (uci_pdu->pduBitmap>>1) & 0x01) + nr_rx_acknack(NULL,uci_pdu,NULL,UL_info,sched_ctrl,stats); + + break; + } + case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4; + + // tpc (power control) + sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30); + + if( (uci_pdu->pduBitmap>>1) & 0x01) + nr_rx_acknack(NULL,NULL,uci_pdu,UL_info,sched_ctrl,stats); + + break; + } + } + } + + UL_info->uci_ind.num_ucis = 0; +} + + void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) { if(nfapi_mode == 1) { diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 5d620181d1..075c77982a 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -64,10 +64,10 @@ int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, return 0; } // L2 Abstraction Layer -int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, fapi_nr_dci_indication_pdu_t *dci){ +int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci){ //printf("handle_dci: rnti %x,dci_type %d\n",rnti,dci_type); - return nr_ue_process_dci_indication_pdu(module_id, cc_id, gNB_index, dci); + return nr_ue_process_dci_indication_pdu(module_id, cc_id, gNB_index, frame, slot, dci); } // L2 Abstraction Layer @@ -110,7 +110,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ ret = nr_ue_scheduler(NULL, ul_info); if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra) - nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx); + nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id); switch(ret){ case UE_CONNECTION_OK: @@ -135,8 +135,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ module_id_t module_id = dl_info->module_id; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; - + if (!dl_info->dci_ind && !dl_info->rx_ind) { // UL indication to schedule DCI reception nr_ue_scheduler(dl_info, NULL); @@ -150,13 +149,15 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ int8_t ret = handle_dci(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, + dl_info->frame, + dl_info->slot, dl_info->dci_ind->dci_list+i); ret_mask |= (ret << FAPI_NR_DCI_IND); if (ret >= 0) { AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is NULL!\n" ); AssertFatal( nr_ue_if_module_inst[module_id]->scheduled_response != NULL, "scheduled_response is NULL!\n" ); - fill_scheduled_response(&scheduled_response, dl_config, ul_config, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot); + fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->thread_id); nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response); } } diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index df2d78f0cb..e78529d437 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -66,8 +66,8 @@ typedef struct { frame_t frame; /// slot int slot; - /// proc is needed to signal back decoded frame number to PHY. However, this is not really FAPI procedure and should be done differently - UE_nr_rxtx_proc_t * proc; + /// index of the current UE RX/TX thread + int thread_id; /// NR UE FAPI-like P7 message, direction: L1 to L2 /// data reception indication structure @@ -95,6 +95,9 @@ typedef struct { frame_t frame_tx; /// slot tx uint32_t slot_tx; + /// index of the current UE RX/TX thread + int thread_id; + /// dci reception indication structure fapi_nr_dci_indication_t *dci_ind; } nr_uplink_indication_t; @@ -111,6 +114,8 @@ typedef struct { frame_t frame; /// slot int slot; + /// index of the current UE RX/TX thread + int thread_id; /// NR UE FAPI-like P7 message, direction: L2 to L1 /// downlink transmission configuration request structure @@ -224,7 +229,7 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, ui \param pduP pointer to pdu*/ int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len); -int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, fapi_nr_dci_indication_pdu_t *dci); +int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci); #endif diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 123167a7af..18b7173a08 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -3295,7 +3295,10 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.present = LTE_MTC_SSB_NR_r15__periodicityAndOffset_r15_PR_sf20_r15; MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.choice.sf20_r15 = 0; MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.ssb_Duration_r15 = LTE_MTC_SSB_NR_r15__ssb_Duration_r15_sf4; - MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz30; + if (rrc_inst->nr_scg_ssb_freq > 2016666) //FR2 + MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz120; + else + MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz30; MeasObj2->measObject.choice.measObjectNR_r15.quantityConfigSet_r15 = 1; MeasObj2->measObject.choice.measObjectNR_r15.ext1 = calloc(1, sizeof(struct LTE_MeasObjectNR_r15__ext1)); @@ -3306,7 +3309,11 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t if (MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15 == NULL) exit(1); MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->present = LTE_MeasObjectNR_r15__ext1__bandNR_r15_PR_setup; - MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 78; + if (rrc_inst->nr_scg_ssb_freq > 2016666) //FR2 + MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 261; + else + MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 78; + ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj2); } @@ -4020,7 +4027,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6; - //<<<<<<< HEAD MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB if (rrc_inst->carrier[0].sib1->tdd_Config!=NULL) { @@ -4635,6 +4641,7 @@ rrc_eNB_process_MeasurementReport( case 7: LOG_D(RRC, "NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe); + printf("NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe); break; default: diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 47a3b6ddf2..11c13eda32 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -159,6 +159,12 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, } /* TODO BCCH SIB1 SIBs */ + if ((Srb_id & RAB_OFFSET ) == BCCH) { + memcpy(&buffer_pP[0], + RC.rrc[Mod_idP]->carrier[CC_id].SIB1_MBMS, + RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_MBMS); + + } /* CCCH */ if( (Srb_id & RAB_OFFSET ) == CCCH) { diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 826be63056..5003e3d7c6 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -226,6 +226,10 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { mib->message.choice.mib->spare.bits_unused = 7; // This makes a spare of 1 bits mib->message.choice.mib->ssb_SubcarrierOffset = (carrier->ssb_SubcarrierOffset)&15; + /* + * The SIB1 will be sent in this allocation (Type0-PDCCH) : 38.213, 13-4 Table and 38.213 13-11 to 13-14 tables + * the reverse allocation is in nr_ue_decode_mib() + */ mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero; mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero; AssertFatal(scc->ssbSubcarrierSpacing != NULL, "scc->ssbSubcarrierSpacing is null\n"); @@ -291,10 +295,6 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration ) { asn_enc_rval_t enc_rval; - NR_BCCH_DL_SCH_Message_t *sib1_message ; - struct NR_SIB1 *sib1 ; - int i; - struct NR_PLMN_IdentityInfo nr_plmn_info; // TODO : Add support for more than one PLMN //int num_plmn = configuration->num_plmn; @@ -302,31 +302,29 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, struct NR_PLMN_Identity nr_plmn[num_plmn]; NR_MCC_MNC_Digit_t nr_mcc_digit[num_plmn][3]; NR_MCC_MNC_Digit_t nr_mnc_digit[num_plmn][3]; + memset(nr_plmn,0,sizeof(nr_plmn)); + memset(nr_mcc_digit,0,sizeof(nr_mcc_digit)); + memset(nr_mnc_digit,0,sizeof(nr_mnc_digit)); + // struct NR_UAC_BarringInfoSet nr_uac_BarringInfoSet; - sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t)); - memset(sib1_message,0,sizeof(NR_BCCH_DL_SCH_Message_t)); + NR_BCCH_DL_SCH_Message_t *sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t)); carrier->siblock1 = sib1_message; sib1_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1; sib1_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1)); - memset(sib1_message->message.choice.c1,0,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1)); sib1_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1; sib1_message->message.choice.c1->choice.systemInformationBlockType1 = CALLOC(1,sizeof(struct NR_SIB1)); - sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1; - memset(sib1,0,sizeof(struct NR_SIB1)); + + struct NR_SIB1 *sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1; sib1->cellSelectionInfo = CALLOC(1,sizeof(struct NR_SIB1__cellSelectionInfo)); - memset(sib1->cellSelectionInfo,0,sizeof(struct NR_SIB1__cellSelectionInfo)); sib1->cellSelectionInfo->q_RxLevMin = -50; - memset(&nr_plmn_info.plmn_IdentityList,0,sizeof(struct NR_PLMN_IdentityInfo__plmn_IdentityList)); - asn_set_empty(&nr_plmn_info.plmn_IdentityList.list); - memset(&nr_plmn_info,0,sizeof(struct NR_PLMN_IdentityInfo)); - memset(nr_plmn,0,num_plmn*sizeof(struct NR_PLMN_Identity)); - for (i = 0; i < num_plmn; ++i) { + struct NR_PLMN_IdentityInfo *nr_plmn_info=CALLOC(1,sizeof(struct NR_PLMN_IdentityInfo)); + asn_set_empty(&nr_plmn_info->plmn_IdentityList.list); + for (int i = 0; i < num_plmn; ++i) { nr_mcc_digit[i][0] = (configuration->mcc[i]/100)%10; nr_mcc_digit[i][1] = (configuration->mcc[i]/10)%10; nr_mcc_digit[i][2] = (configuration->mcc[i])%10; nr_plmn[i].mcc = CALLOC(1,sizeof(struct NR_MCC)); - memset(nr_plmn[i].mcc,0,sizeof(struct NR_MCC)); asn_set_empty(&nr_plmn[i].mcc->list); ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][0]); ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][1]); @@ -334,26 +332,23 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, nr_mnc_digit[i][0] = (configuration->mnc[i]/100)%10; nr_mnc_digit[i][1] = (configuration->mnc[i]/10)%10; nr_mnc_digit[i][2] = (configuration->mnc[i])%10; - memset(&nr_plmn[i].mnc,0,sizeof(NR_MNC_t)); nr_plmn[i].mnc.list.size=0; nr_plmn[i].mnc.list.count=0; ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][0]); ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][1]); ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][2]); - ASN_SEQUENCE_ADD(&nr_plmn_info.plmn_IdentityList.list, &nr_plmn[i]); + ASN_SEQUENCE_ADD(&nr_plmn_info->plmn_IdentityList.list, &nr_plmn[i]); }//end plmn loop - nr_plmn_info.cellIdentity.buf = MALLOC(8); - memset(nr_plmn_info.cellIdentity.buf,0,8); - nr_plmn_info.cellIdentity.buf[0]= (configuration->cell_identity >> 20) & 0xff; - nr_plmn_info.cellIdentity.buf[1]= (configuration->cell_identity >> 12) & 0xff; - nr_plmn_info.cellIdentity.buf[2]= (configuration->cell_identity >> 4) & 0xff; - nr_plmn_info.cellIdentity.buf[3]= (configuration->cell_identity << 4) & 0xff; - nr_plmn_info.cellIdentity.size= 4; - nr_plmn_info.cellIdentity.bits_unused= 4; - nr_plmn_info.cellReservedForOperatorUse = 0; - memset(&sib1->cellAccessRelatedInfo,0,sizeof(NR_CellAccessRelatedInfo_t)); - ASN_SEQUENCE_ADD(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list, &nr_plmn_info); + nr_plmn_info->cellIdentity.buf = CALLOC(1,8); + nr_plmn_info->cellIdentity.buf[0]= (configuration->cell_identity >> 20) & 0xff; + nr_plmn_info->cellIdentity.buf[1]= (configuration->cell_identity >> 12) & 0xff; + nr_plmn_info->cellIdentity.buf[2]= (configuration->cell_identity >> 4) & 0xff; + nr_plmn_info->cellIdentity.buf[3]= (configuration->cell_identity << 4) & 0xff; + nr_plmn_info->cellIdentity.size= 4; + nr_plmn_info->cellIdentity.bits_unused= 4; + nr_plmn_info->cellReservedForOperatorUse = 0; + ASN_SEQUENCE_ADD(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list, nr_plmn_info); #if 0 sib1->uac_BarringInfo = CALLOC(1, sizeof(struct NR_SIB1__uac_BarringInfo)); memset(sib1->uac_BarringInfo, 0, sizeof(struct NR_SIB1__uac_BarringInfo)); @@ -366,11 +361,12 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, ASN_SEQUENCE_ADD(&sib1->uac_BarringInfo->uac_BarringInfoSetList, &nr_uac_BarringInfoSet); #endif //encode SIB1 to data + carrier->SIB1=(uint8_t *) malloc16(128); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, NULL, (void *)sib1_message, carrier->SIB1, - 100); + 128); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); @@ -942,6 +938,11 @@ uint8_t do_NR_RRCConnectionRelease(uint8_t *buffer, (void *)&dl_dcch_msg, buffer, RRC_BUF_SIZE); + if(enc_rval.encoded == -1) { + LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } return((enc_rval.encoded+7)/8); } @@ -1248,11 +1249,14 @@ enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg, buffer, 100); +AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name,enc_rval.encoded); +LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); - AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name,enc_rval.encoded); - LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +return((enc_rval.encoded+7)/8); +} - return((enc_rval.encoded+7)/8); +int do_DLInformationTransfer_NR (void * p) { + return 0; } diff --git a/common/utils/memory_pools.h b/openair2/RRC/NR/nr_ngap_gNB.c similarity index 54% rename from common/utils/memory_pools.h rename to openair2/RRC/NR/nr_ngap_gNB.c index 1c1997f7f2..0d4892bb88 100644 --- a/common/utils/memory_pools.h +++ b/openair2/RRC/NR/nr_ngap_gNB.c @@ -9,6 +9,8 @@ * * http://www.openairinterface.org/?page_id=698 * + * Author and copyright: Laurent Thomas, open-cells.com + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,25 +20,38 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ +#include +#include -#ifndef MEMORY_POOLS_H_ -#define MEMORY_POOLS_H_ +void rrc_gNB_process_NGAP_DOWNLINK_NAS (void ) { + do_DLInformationTransfer(0,NULL,0,0,NULL); + // send it as DL data +/* + rrc_data_req ( + &ctxt, + srb_id, + (*rrc_eNB_mui)++, + SDU_CONFIRM_NO, + length, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +*/ -#include +} -typedef void * memory_pools_handle_t; -typedef void * memory_pool_item_handle_t; +void rrc_gNB_send_NGAP_NAS_FIRST_REQ(void ) { + // We are noCore only now + // create message that should come from 5GC + + // send it dow + rrc_gNB_process_NGAP_DOWNLINK_NAS(); +} -memory_pools_handle_t memory_pools_create (uint32_t pools_number); +void nr_rrc_rx_tx() { + // check timers -char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle); + // check if UEs are lost, to remove them from upper layers -int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t pool_items_number, uint32_t pool_item_size); + // -memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_pools_handle, uint32_t item_size, uint16_t info_0, uint16_t info_1); - -int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, uint16_t info_0); - -void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, int index, uint16_t info); - -#endif /* MEMORY_POOLS_H_ */ +} diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 438b76bf37..27118ee523 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -110,6 +110,8 @@ rrc_gNB_generate_UECapabilityEnquiry( rrc_gNB_ue_context_t *const ue_context_pP ); +void nr_rrc_rx_tx(void); + /**\brief RRC eNB task. \param void *args_p Pointer on arguments to start the task. */ void *rrc_gnb_task(void *args_p); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 13ab6f5741..71e0bd13ad 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -85,7 +85,7 @@ #include "executables/softmodem-common.h" #include -#include "x2ap_eNB.h" +#include #include "BIT_STRING.h" #include "assertions.h" @@ -208,10 +208,11 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge( ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// -static void init_NR_SI(gNB_RRC_INST *rrc) { +static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration) { LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); rrc->carrier.MIB = (uint8_t *) malloc16(4); rrc->carrier.sizeof_MIB = do_MIB_NR(rrc,0); + rrc->carrier.sizeof_SIB1 = do_SIB1_NR(&rrc->carrier,configuration); LOG_I(NR_RRC,"Done init_NR_SI\n"); rrc_mac_config_req_gNB(rrc->module_id, rrc->carrier.ssb_SubcarrierOffset, @@ -301,7 +302,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu rrc->carrier.pucch_TargetSNRx10 = configuration->pucch_TargetSNRx10; /// System Information INIT LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Checking release \n",PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt)); - init_NR_SI(rrc); + init_NR_SI(rrc, configuration); rrc_init_nr_global_param(); openair_nr_rrc_on(&ctxt); return 0; @@ -331,27 +332,6 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x parse_CG_ConfigInfo(rrc,cg_configinfo,m); } -void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m) -{ - gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP]; - rrc_remove_nsa_user(rrc, m->rnti); -} - -void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC_dc_overall_timeout_t *m) -{ - gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP]; - rrc_remove_nsa_user(rrc, m->rnti); -} - -void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { - MessageDef *msg; - - /* send a tick to x2ap */ - if (is_x2ap_enabled()){ - msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS); - itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg); - } -} //----------------------------------------------------------------------------- uint8_t @@ -360,10 +340,10 @@ rrc_gNB_get_next_transaction_identifier( ) //----------------------------------------------------------------------------- { - static uint8_t nr_rrc_transaction_identifier[NUMBER_OF_gNB_MAX]; - nr_rrc_transaction_identifier[gnb_mod_idP] = (nr_rrc_transaction_identifier[gnb_mod_idP] + 1) % NR_RRC_TRANSACTION_IDENTIFIER_NUMBER; - LOG_T(NR_RRC, "generated xid is %d\n", nr_rrc_transaction_identifier[gnb_mod_idP]); - return nr_rrc_transaction_identifier[gnb_mod_idP]; + static uint8_t nr_rrc_transaction_identifier[NUMBER_OF_gNB_MAX]; + nr_rrc_transaction_identifier[gnb_mod_idP] = (nr_rrc_transaction_identifier[gnb_mod_idP] + 1) % NR_RRC_TRANSACTION_IDENTIFIER_NUMBER; + LOG_T(NR_RRC, "generated xid is %d\n", nr_rrc_transaction_identifier[gnb_mod_idP]); + return nr_rrc_transaction_identifier[gnb_mod_idP]; } //----------------------------------------------------------------------------- @@ -375,63 +355,63 @@ rrc_gNB_generate_RRCSetup( ) //----------------------------------------------------------------------------- { - LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup \n"); - NR_SRB_ToAddModList_t *SRB_configList = NULL; + LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup \n"); + NR_SRB_ToAddModList_t *SRB_configList = NULL; - // T(T_GNB_RRC_SETUP, - // T_INT(ctxt_pP->module_id), - // T_INT(ctxt_pP->frame), - // T_INT(ctxt_pP->subframe), - // T_INT(ctxt_pP->rnti)); - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - SRB_configList = ue_p->SRB_configList; - ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ctxt_pP, - ue_context_pP, - CC_id, - (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, - rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), - SRB_configList); + // T(T_GNB_RRC_SETUP, + // T_INT(ctxt_pP->module_id), + // T_INT(ctxt_pP->frame), + // T_INT(ctxt_pP->subframe), + // T_INT(ctxt_pP->rnti)); + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + SRB_configList = ue_p->SRB_configList; + ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ctxt_pP, + ue_context_pP, + CC_id, + (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, + rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), + SRB_configList); - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, - (char *)(ue_p->Srb0.Tx_buffer.Payload), - ue_p->Srb0.Tx_buffer.payload_size, - "[MSG] RRC Setup\n"); + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, + (char *)(ue_p->Srb0.Tx_buffer.Payload), + ue_p->Srb0.Tx_buffer.payload_size, + "[MSG] RRC Setup\n"); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - // rrc_mac_config_req_eNB + // rrc_mac_config_req_eNB - MSC_LOG_TX_MESSAGE( - MSC_RRC_GNB, - MSC_RRC_UE, - ue_p->Srb0.Tx_buffer.Header, // LG WARNING - ue_p->Srb0.Tx_buffer.payload_size, - MSC_AS_TIME_FMT" RRCSetup UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_context.rnti, - ue_p->Srb0.Tx_buffer.payload_size); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_p->Srb0.Tx_buffer.payload_size); - // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE - ue_context_pP->ue_context.ue_release_timer = 1; - // remove UE after 10 frames after RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres = 1000; - /* init timers */ - // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; + MSC_LOG_TX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + ue_p->Srb0.Tx_buffer.Header, // LG WARNING + ue_p->Srb0.Tx_buffer.payload_size, + MSC_AS_TIME_FMT" RRCSetup UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + ue_p->Srb0.Tx_buffer.payload_size); + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_p->Srb0.Tx_buffer.payload_size); + // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE + ue_context_pP->ue_context.ue_release_timer = 1; + // remove UE after 10 frames after RRCConnectionRelease is triggered + ue_context_pP->ue_context.ue_release_timer_thres = 1000; + /* init timers */ + // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, - ue_p->Srb0.Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_CCCH_DATA_IND); - GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, + ue_p->Srb0.Tx_buffer.payload_size); + memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); + message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_CCCH_DATA_IND); + GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); #endif } @@ -443,37 +423,37 @@ rrc_gNB_generate_RRCReject( ) //----------------------------------------------------------------------------- { - LOG_I(NR_RRC, "rrc_gNB_generate_RRCReject \n"); - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - ue_p->Srb0.Tx_buffer.payload_size = do_RRCReject(ctxt_pP->module_id, - (uint8_t *)ue_p->Srb0.Tx_buffer.Payload); - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, - (char *)(ue_p->Srb0.Tx_buffer.Payload), - ue_p->Srb0.Tx_buffer.payload_size, - "[MSG] RRCReject \n"); - MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, - MSC_RRC_UE, - ue_p->Srb0.Tx_buffer.Header, - ue_p->Srb0.Tx_buffer.payload_size, - MSC_AS_TIME_FMT" NR_RRCReject UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti, - ue_p->Srb0.Tx_buffer.payload_size); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating NR_RRCReject (bytes %d)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_p->Srb0.Tx_buffer.payload_size); + LOG_I(NR_RRC, "rrc_gNB_generate_RRCReject \n"); + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + ue_p->Srb0.Tx_buffer.payload_size = do_RRCReject(ctxt_pP->module_id, + (uint8_t *)ue_p->Srb0.Tx_buffer.Payload); + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, + (char *)(ue_p->Srb0.Tx_buffer.Payload), + ue_p->Srb0.Tx_buffer.payload_size, + "[MSG] RRCReject \n"); + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, + MSC_RRC_UE, + ue_p->Srb0.Tx_buffer.Header, + ue_p->Srb0.Tx_buffer.payload_size, + MSC_AS_TIME_FMT" NR_RRCReject UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti, + ue_p->Srb0.Tx_buffer.payload_size); + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating NR_RRCReject (bytes %d)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_p->Srb0.Tx_buffer.payload_size); #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, - ue_p->Srb0.Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_CCCH_DATA_IND); - GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, + ue_p->Srb0.Tx_buffer.payload_size); + memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); + message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_CCCH_DATA_IND); + GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); #endif } @@ -489,16 +469,16 @@ rrc_gNB_process_RRCSetupComplete( ) //----------------------------------------------------------------------------- { - LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing NR_RRCSetupComplete from UE (SRB1 Active)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - ue_context_pP->ue_context.Srb1.Active = 1; - ue_context_pP->ue_context.Status = NR_RRC_CONNECTED; + LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing NR_RRCSetupComplete from UE (SRB1 Active)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + ue_context_pP->ue_context.Srb1.Active = 1; + ue_context_pP->ue_context.Status = NR_RRC_CONNECTED; - if (AMF_MODE_ENABLED) { - rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete); - } else { - rrc_gNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP); - } + if (AMF_MODE_ENABLED) { + rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete); + } else { + rrc_gNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP); + } } //----------------------------------------------------------------------------- @@ -509,61 +489,61 @@ rrc_gNB_generate_defaultRRCReconfiguration( ) //----------------------------------------------------------------------------- { - // gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - uint8_t buffer[RRC_BUF_SIZE]; - uint16_t size; - gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; + // gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size; + gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; - size = do_RRCReconfiguration(ctxt_pP, ue_context_pP, buffer, - rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), - gnb_rrc_inst); - LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n"); + size = do_RRCReconfiguration(ctxt_pP, ue_context_pP, buffer, + rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), + gnb_rrc_inst); + LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n"); - free(ue_context_pP->ue_context.nas_pdu.buffer); + free(ue_context_pP->ue_context.nas_pdu.buffer); - LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %x)\n", - ctxt_pP->module_id, - ctxt_pP->frame, - size, - ue_context_pP->ue_context.rnti); - LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", - ctxt_pP->frame, - ctxt_pP->module_id, - size, - ue_context_pP->ue_context.rnti, - rrc_gNB_mui, - ctxt_pP->module_id, - DCCH); - MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, - MSC_RRC_UE, - buffer, - size, - MSC_AS_TIME_FMT" NR_RRCReconfiguration UE %x MUI %d size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_context.rnti, - rrc_gNB_mui, - size); + LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %x)\n", + ctxt_pP->module_id, + ctxt_pP->frame, + size, + ue_context_pP->ue_context.rnti); + LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", + ctxt_pP->frame, + ctxt_pP->module_id, + size, + ue_context_pP->ue_context.rnti, + rrc_gNB_mui, + ctxt_pP->module_id, + DCCH); + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" NR_RRCReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_gNB_mui, + size); #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); #else - nr_rrc_data_req(ctxt_pP, - DCCH, - rrc_gNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + nr_rrc_data_req(ctxt_pP, + DCCH, + rrc_gNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); #endif - // rrc_pdcp_config_asn1_req - // rrc_rlc_config_asn1_req + // rrc_pdcp_config_asn1_req + // rrc_rlc_config_asn1_req } //----------------------------------------------------------------------------- @@ -577,153 +557,153 @@ rrc_gNB_process_RRCReconfigurationComplete( const uint8_t xid ) { - int drb_id; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; - NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; - NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; - NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; - NR_DRB_Identity_t *drb_id_p = NULL; - uint8_t nr_DRB2LCHAN[8]; + int drb_id; + uint8_t *kRRCenc = NULL; + uint8_t *kRRCint = NULL; + uint8_t *kUPenc = NULL; + NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; + NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; + NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; + NR_DRB_Identity_t *drb_id_p = NULL; + uint8_t nr_DRB2LCHAN[8]; - ue_context_pP->ue_context.ue_reestablishment_timer = 0; + ue_context_pP->ue_context.ue_reestablishment_timer = 0; #ifndef PHYSIM - /* Derive the keys from kgnb */ - if (DRB_configList != NULL) { - derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kgnb, - &kUPenc); - } + /* Derive the keys from kgnb */ + if (DRB_configList != NULL) { + derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, + ue_context_pP->ue_context.kgnb, + &kUPenc); + } - derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kgnb, - &kRRCenc); - derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kgnb, - &kRRCint); + derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, + ue_context_pP->ue_context.kgnb, + &kRRCenc); + derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, + ue_context_pP->ue_context.kgnb, + &kRRCint); #endif - /* Refresh SRBs/DRBs */ - MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_context.rnti); + /* Refresh SRBs/DRBs */ + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti); #ifndef ITTI_SIM - nr_rrc_pdcp_config_asn1_req(ctxt_pP, - SRB_configList, // NULL, - DRB_configList, - DRB_Release_configList2, - 0xff, // already configured during the securitymodecommand - kRRCenc, - kRRCint, - kUPenc, - NULL, - NULL, - NULL); - /* Refresh SRBs/DRBs */ - nr_rrc_rlc_config_asn1_req(ctxt_pP, - SRB_configList, // NULL, - DRB_configList, - DRB_Release_configList2, - NULL, - NULL); + nr_rrc_pdcp_config_asn1_req(ctxt_pP, + SRB_configList, // NULL, + DRB_configList, + DRB_Release_configList2, + 0xff, // already configured during the securitymodecommand + kRRCenc, + kRRCint, + kUPenc, + NULL, + NULL, + NULL); + /* Refresh SRBs/DRBs */ + nr_rrc_rlc_config_asn1_req(ctxt_pP, + SRB_configList, // NULL, + DRB_configList, + DRB_Release_configList2, + NULL, + NULL); #endif - /* Set the SRB active in UE context */ - if (SRB_configList != NULL) { - for (int i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { - if (SRB_configList->list.array[i]->srb_Identity == 1) { - ue_context_pP->ue_context.Srb1.Active = 1; - } else if (SRB_configList->list.array[i]->srb_Identity == 2) { - ue_context_pP->ue_context.Srb2.Active = 1; - ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; - LOG_I(NR_RRC,"[gNB %d] Frame %d CC %d : SRB2 is now active\n", - ctxt_pP->module_id, - ctxt_pP->frame, - ue_context_pP->ue_context.primaryCC_id); - } else { - LOG_W(NR_RRC,"[gNB %d] Frame %d CC %d : invalide SRB identity %ld\n", - ctxt_pP->module_id, - ctxt_pP->frame, - ue_context_pP->ue_context.primaryCC_id, - SRB_configList->list.array[i]->srb_Identity); - } + /* Set the SRB active in UE context */ + if (SRB_configList != NULL) { + for (int i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { + if (SRB_configList->list.array[i]->srb_Identity == 1) { + ue_context_pP->ue_context.Srb1.Active = 1; + } else if (SRB_configList->list.array[i]->srb_Identity == 2) { + ue_context_pP->ue_context.Srb2.Active = 1; + ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; + LOG_I(NR_RRC,"[gNB %d] Frame %d CC %d : SRB2 is now active\n", + ctxt_pP->module_id, + ctxt_pP->frame, + ue_context_pP->ue_context.primaryCC_id); + } else { + LOG_W(NR_RRC,"[gNB %d] Frame %d CC %d : invalide SRB identity %ld\n", + ctxt_pP->module_id, + ctxt_pP->frame, + ue_context_pP->ue_context.primaryCC_id, + SRB_configList->list.array[i]->srb_Identity); } - - free(SRB_configList); - ue_context_pP->ue_context.SRB_configList2[xid] = NULL; } - /* Loop through DRBs and establish if necessary */ - if (DRB_configList != NULL) { - for (int i = 0; i < DRB_configList->list.count; i++) { - if (DRB_configList->list.array[i]) { - drb_id = (int)DRB_configList->list.array[i]->drb_Identity; - LOG_I(NR_RRC, "[gNB %d] Frame %d : Logical Channel UL-DCCH, Received NR_RRCReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n", - ctxt_pP->module_id, - ctxt_pP->frame, - ctxt_pP->rnti, - (int)DRB_configList->list.array[i]->drb_Identity, - (int)*DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel); + free(SRB_configList); + ue_context_pP->ue_context.SRB_configList2[xid] = NULL; + } - if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) { - ue_context_pP->ue_context.DRB_active[drb_id] = 1; - LOG_D(NR_RRC, "[gNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", - ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); + /* Loop through DRBs and establish if necessary */ + if (DRB_configList != NULL) { + for (int i = 0; i < DRB_configList->list.count; i++) { + if (DRB_configList->list.array[i]) { + drb_id = (int)DRB_configList->list.array[i]->drb_Identity; + LOG_I(NR_RRC, "[gNB %d] Frame %d : Logical Channel UL-DCCH, Received NR_RRCReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n", + ctxt_pP->module_id, + ctxt_pP->frame, + ctxt_pP->rnti, + (int)DRB_configList->list.array[i]->drb_Identity, + (int)*DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (DRB) ---> MAC_gNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) { + ue_context_pP->ue_context.DRB_active[drb_id] = 1; + LOG_D(NR_RRC, "[gNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", + ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); - if (DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel) { - nr_DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel; - } + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (DRB) ---> MAC_gNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - // rrc_mac_config_req_eNB - } else { // remove LCHAN from MAC/PHY - if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { - // DRB has just been removed so remove RLC + PDCP for DRB - /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, - (ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE); - */ - rrc_rlc_config_req(ctxt_pP, - SRB_FLAG_NO, - MBMS_FLAG_NO, - CONFIG_ACTION_REMOVE, - nr_DRB2LCHAN[i], - Rlc_info_um); - } - - ue_context_pP->ue_context.DRB_active[drb_id] = 0; - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + if (DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel) { + nr_DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel; + } // rrc_mac_config_req_eNB + } else { // remove LCHAN from MAC/PHY + if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { + // DRB has just been removed so remove RLC + PDCP for DRB + /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, + (ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE); + */ + rrc_rlc_config_req(ctxt_pP, + SRB_FLAG_NO, + MBMS_FLAG_NO, + CONFIG_ACTION_REMOVE, + nr_DRB2LCHAN[i], + Rlc_info_um); + } - } // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) - } // end if (DRB_configList->list.array[i]) - } // end for (int i = 0; i < DRB_configList->list.count; i++) + ue_context_pP->ue_context.DRB_active[drb_id] = 0; + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - free(DRB_configList); - ue_context_pP->ue_context.DRB_configList2[xid] = NULL; - } // end if DRB_configList != NULL + // rrc_mac_config_req_eNB - if(DRB_Release_configList2 != NULL) { - for (int i = 0; i < DRB_Release_configList2->list.count; i++) { - if (DRB_Release_configList2->list.array[i]) { - drb_id_p = DRB_Release_configList2->list.array[i]; - drb_id = *drb_id_p; + } // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) + } // end if (DRB_configList->list.array[i]) + } // end for (int i = 0; i < DRB_configList->list.count; i++) - if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { - ue_context_pP->ue_context.DRB_active[drb_id] = 0; - } - } + free(DRB_configList); + ue_context_pP->ue_context.DRB_configList2[xid] = NULL; + } // end if DRB_configList != NULL + + if(DRB_Release_configList2 != NULL) { + for (int i = 0; i < DRB_Release_configList2->list.count; i++) { + if (DRB_Release_configList2->list.array[i]) { + drb_id_p = DRB_Release_configList2->list.array[i]; + drb_id = *drb_id_p; + + if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { + ue_context_pP->ue_context.DRB_active[drb_id] = 0; } - - free(DRB_Release_configList2); - ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL; + } } + + free(DRB_Release_configList2); + ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL; + } } //----------------------------------------------------------------------------- @@ -733,177 +713,177 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, int buffer_length, const int CC_id) { - asn_dec_rval_t dec_rval; - NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; - NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL; - uint64_t random_value = 0; + asn_dec_rval_t dec_rval; + NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; + NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL; + uint64_t random_value = 0; - dec_rval = uper_decode( NULL, - &asn_DEF_NR_UL_CCCH_Message, - (void **)&ul_ccch_msg, - (uint8_t *) buffer, - 100, - 0, - 0); + dec_rval = uper_decode( NULL, + &asn_DEF_NR_UL_CCCH_Message, + (void **)&ul_ccch_msg, + (uint8_t *) buffer, + 100, + 0, + 0); - if (dec_rval.consumed == 0) { + if (dec_rval.consumed == 0) { + /* TODO */ + LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + return -1; + } + + if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { + switch (ul_ccch_msg->message.choice.c1->present) { + case NR_UL_CCCH_MessageType__c1_PR_NOTHING: /* TODO */ - LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - return -1; - } + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n", + PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP)); + break; - if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { - switch (ul_ccch_msg->message.choice.c1->present) { - case NR_UL_CCCH_MessageType__c1_PR_NOTHING: - /* TODO */ - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n", - PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP)); - break; + case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: + ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti); + if (ue_context_p != NULL) { + rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_p); + MSC_LOG_RX_DISCARDED_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + buffer, + dec_rval.consumed, + MSC_AS_TIME_FMT" NR_RRCSetupRequest UE %x size %u (UE already in context)", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + dec_rval.consumed); + } else { + rrcSetupRequest = &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest; + if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { + /* randomValue BIT STRING (SIZE (39)) */ + if (rrcSetupRequest->ue_Identity.choice.randomValue.size != 5) { // 39-bit random value + LOG_E(NR_RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", + (long unsigned int)rrcSetupRequest->ue_Identity.choice.randomValue.size); + return -1; + } - case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: - ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti); - if (ue_context_p != NULL) { - rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_p); - MSC_LOG_RX_DISCARDED_MESSAGE( - MSC_RRC_GNB, - MSC_RRC_UE, - buffer, - dec_rval.consumed, - MSC_AS_TIME_FMT" NR_RRCSetupRequest UE %x size %u (UE already in context)", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - dec_rval.consumed); - } else { - rrcSetupRequest = &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest; - if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { - /* randomValue BIT STRING (SIZE (39)) */ - if (rrcSetupRequest->ue_Identity.choice.randomValue.size != 5) { // 39-bit random value - LOG_E(NR_RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", - (long unsigned int)rrcSetupRequest->ue_Identity.choice.randomValue.size); - return -1; - } + memcpy(((uint8_t *) & random_value) + 3, + rrcSetupRequest->ue_Identity.choice.randomValue.buf, + rrcSetupRequest->ue_Identity.choice.randomValue.size); - memcpy(((uint8_t *) & random_value) + 3, - rrcSetupRequest->ue_Identity.choice.randomValue.buf, - rrcSetupRequest->ue_Identity.choice.randomValue.size); + /* if there is already a registered UE (with another RNTI) with this random_value, + * the current one must be removed from MAC/PHY (zombie UE) + */ + if ((ue_context_p = rrc_gNB_ue_context_random_exist(RC.nrrrc[ctxt_pP->module_id], random_value))) { + LOG_W(NR_RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n", + ctxt_pP->rnti, ue_context_p->ue_context.rnti, ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ul_failure_timer = 20000; + } - /* if there is already a registered UE (with another RNTI) with this random_value, - * the current one must be removed from MAC/PHY (zombie UE) - */ - if ((ue_context_p = rrc_gNB_ue_context_random_exist(RC.nrrrc[ctxt_pP->module_id], random_value))) { - LOG_W(NR_RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n", - ctxt_pP->rnti, ue_context_p->ue_context.rnti, ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ul_failure_timer = 20000; - } + ue_context_p = rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], random_value); + ue_context_p->ue_context.Srb0.Srb_id = 0; + ue_context_p->ue_context.Srb0.Active = 1; + memcpy(ue_context_p->ue_context.Srb0.Rx_buffer.Payload, + buffer, + buffer_length); + ue_context_p->ue_context.Srb0.Rx_buffer.payload_size = buffer_length; + } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { + /* TODO */ + /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ + /* ng-5G-S-TMSI-Part1 BIT STRING (SIZE (39)) */ + if (rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size != 5) { + LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part1 size, expected 5, provided %lu \n", + (long unsigned int)rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); + return -1; + } - ue_context_p = rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], random_value); - ue_context_p->ue_context.Srb0.Srb_id = 0; - ue_context_p->ue_context.Srb0.Active = 1; - memcpy(ue_context_p->ue_context.Srb0.Rx_buffer.Payload, - buffer, - buffer_length); - ue_context_p->ue_context.Srb0.Rx_buffer.payload_size = buffer_length; - } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { - /* TODO */ - /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ - /* ng-5G-S-TMSI-Part1 BIT STRING (SIZE (39)) */ - if (rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size != 5) { - LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part1 size, expected 5, provided %lu \n", - (long unsigned int)rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); - return -1; - } + uint64_t s_tmsi_part1 = bitStr_to_uint64(&rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1); - uint64_t s_tmsi_part1 = bitStr_to_uint64(&rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1); + // memcpy(((uint8_t *) & random_value) + 3, + // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.buf, + // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); - // memcpy(((uint8_t *) & random_value) + 3, - // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.buf, - // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); + if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(RC.nrrrc[ctxt_pP->module_id], s_tmsi_part1))) { + LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p, ue_context_p->ue_context.rnti, ctxt_pP->rnti); - if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(RC.nrrrc[ctxt_pP->module_id], s_tmsi_part1))) { - LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p, ue_context_p->ue_context.rnti, ctxt_pP->rnti); + nr_rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti); - nr_rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti); + /* replace rnti in the context */ + /* for that, remove the context from the RB tree */ + RB_REMOVE(rrc_nr_ue_tree_s, &RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); + /* and insert again, after changing rnti everywhere it has to be changed */ + ue_context_p->ue_id_rnti = ctxt_pP->rnti; + ue_context_p->ue_context.rnti = ctxt_pP->rnti; + RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); + /* reset timers */ + ue_context_p->ue_context.ul_failure_timer = 0; + ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + ue_context_p->ue_context.ue_release_timer_s1 = 0; + ue_context_p->ue_context.ue_release_timer_rrc = 0; + } else { + LOG_I(NR_RRC, " 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 to %p => %ld\n", + ue_context_p, s_tmsi_part1); - /* replace rnti in the context */ - /* for that, remove the context from the RB tree */ - RB_REMOVE(rrc_nr_ue_tree_s, &RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); - /* and insert again, after changing rnti everywhere it has to be changed */ - ue_context_p->ue_id_rnti = ctxt_pP->rnti; - ue_context_p->ue_context.rnti = ctxt_pP->rnti; - RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); - /* reset timers */ - ue_context_p->ue_context.ul_failure_timer = 0; - ue_context_p->ue_context.ue_release_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - ue_context_p->ue_context.ue_release_timer_s1 = 0; - ue_context_p->ue_context.ue_release_timer_rrc = 0; - } else { - LOG_I(NR_RRC, " 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 to %p => %ld\n", - ue_context_p, s_tmsi_part1); + ue_context_p = rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], s_tmsi_part1); - ue_context_p = rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], s_tmsi_part1); + if (ue_context_p == NULL) { + LOG_E(RRC, "%s:%d:%s: rrc_gNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__); + } - if (ue_context_p == NULL) { - LOG_E(RRC, "%s:%d:%s: rrc_gNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__); - } + if (ue_context_p != NULL) { + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = TRUE; + ue_context_p->ue_context.ng_5G_S_TMSI_Part1 = s_tmsi_part1; + } + } + } else { + /* TODO */ + memcpy(((uint8_t *) & random_value) + 3, + rrcSetupRequest->ue_Identity.choice.randomValue.buf, + rrcSetupRequest->ue_Identity.choice.randomValue.size); - if (ue_context_p != NULL) { - ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = TRUE; - ue_context_p->ue_context.ng_5G_S_TMSI_Part1 = s_tmsi_part1; - } - } - } else { - /* TODO */ - memcpy(((uint8_t *) & random_value) + 3, - rrcSetupRequest->ue_Identity.choice.randomValue.buf, - rrcSetupRequest->ue_Identity.choice.randomValue.size); - - rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], random_value); - LOG_E(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_gNB_generate_RRCReject(ctxt_pP, - rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), - CC_id); - break; - } - } - - if (ue_context_p != NULL) { - ue_context_p->ue_context.establishment_cause = rrcSetupRequest->establishmentCause; - } - - rrc_gNB_generate_RRCSetup(ctxt_pP, - rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), - CC_id); - break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: - LOG_I(NR_RRC, "receive rrcResumeRequest message \n"); - /* TODO */ - break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: - LOG_I(NR_RRC, "receive rrcReestablishmentRequest message \n"); - /* TODO */ - break; - - case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: - LOG_I(NR_RRC, "receive rrcSystemInfoRequest message \n"); - /* TODO */ - break; - - default: - LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Unknown message\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - break; + rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], random_value); + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + rrc_gNB_generate_RRCReject(ctxt_pP, + rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), + CC_id); + break; + } } + + if (ue_context_p != NULL) { + ue_context_p->ue_context.establishment_cause = rrcSetupRequest->establishmentCause; + } + + rrc_gNB_generate_RRCSetup(ctxt_pP, + rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), + CC_id); + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: + LOG_I(NR_RRC, "receive rrcResumeRequest message \n"); + /* TODO */ + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: + LOG_I(NR_RRC, "receive rrcReestablishmentRequest message \n"); + /* TODO */ + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: + LOG_I(NR_RRC, "receive rrcSystemInfoRequest message \n"); + /* TODO */ + break; + + default: + LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Unknown message\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + break; } - return 0; + } + return 0; } /*! \fn uint64_t bitStr_to_uint64(BIT_STRING_t *) @@ -939,322 +919,344 @@ rrc_gNB_decode_dcch( ) //----------------------------------------------------------------------------- { - asn_dec_rval_t dec_rval; - NR_UL_DCCH_Message_t *ul_dcch_msg = NULL; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - // NR_RRCSetupComplete_t *rrcSetupComplete = NULL; + asn_dec_rval_t dec_rval; + NR_UL_DCCH_Message_t *ul_dcch_msg = NULL; + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + // NR_RRCSetupComplete_t *rrcSetupComplete = NULL; - int i; + int i; - if ((Srb_id != 1) && (Srb_id != 2)) { + if ((Srb_id != 1) && (Srb_id != 2)) { LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received message on SRB%ld, should not have ...\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - Srb_id); - } else { - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received message on SRB%ld\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - Srb_id); + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + Srb_id); + } else { + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received message on SRB%ld\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + Srb_id); + } + + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Decoding UL-DCCH Message\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + dec_rval = uper_decode( + NULL, + &asn_DEF_NR_UL_DCCH_Message, + (void **)&ul_dcch_msg, + Rx_sdu, + sdu_sizeP, + 0, + 0); + // xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); + + { + for (i = 0; i < sdu_sizeP; i++) { + LOG_T(NR_RRC, "%x.", Rx_sdu[i]); } - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Decoding UL-DCCH Message\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - dec_rval = uper_decode( - NULL, - &asn_DEF_NR_UL_DCCH_Message, - (void **)&ul_dcch_msg, - Rx_sdu, - sdu_sizeP, - 0, - 0); - // xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); + LOG_T(NR_RRC, "\n"); + } - { - for (i = 0; i < sdu_sizeP; i++) { - LOG_T(NR_RRC, "%x.", Rx_sdu[i]); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode UL-DCCH (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + dec_rval.consumed); + return -1; + } + + ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], + ctxt_pP->rnti); + + if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) { + switch (ul_dcch_msg->message.choice.c1->present) { + case NR_UL_DCCH_MessageType__c1_PR_NOTHING: + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-DCCH-Message\n", + PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP)); + break; + + case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete: + if(!ue_context_p) { + LOG_I(NR_RRC, "Processing NR_RRCReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; } - LOG_T(NR_RRC, "\n"); - } - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode UL-DCCH (%zu bytes)\n", + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(Rx_sdu), sdu_sizeP, + "[MSG] RRC Connection Reconfiguration Complete\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" NR_RRCReconfigurationComplete UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(RRCReconfigurationComplete) ---> RRC_gNB]\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - dec_rval.consumed); - return -1; - } + DCCH, + sdu_sizeP); - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], - ctxt_pP->rnti); + if (ul_dcch_msg->message.choice.c1->present == NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete) { + if (ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->criticalExtensions.present == + NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete) + rrc_gNB_process_RRCReconfigurationComplete( + ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); + } - if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) { - switch (ul_dcch_msg->message.choice.c1->present) { - case NR_UL_DCCH_MessageType__c1_PR_NOTHING: - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-DCCH-Message\n", - PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP)); - break; + rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); - case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete: - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing NR_RRCReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); - break; - } + break; - LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(Rx_sdu), sdu_sizeP, - "[MSG] RRC Connection Reconfiguration Complete\n"); - MSC_LOG_RX_MESSAGE( + case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete: + if(!ue_context_p) { + LOG_I(NR_RRC, "Processing NR_RRCSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; + } + + LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC SetupComplete\n"); + MSC_LOG_RX_MESSAGE( MSC_RRC_GNB, MSC_RRC_UE, Rx_sdu, sdu_sizeP, - MSC_AS_TIME_FMT" NR_RRCReconfigurationComplete UE %x size %u", + MSC_AS_TIME_FMT" NR_RRCSetupComplete UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_p->ue_context.rnti, sdu_sizeP); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(RRCReconfigurationComplete) ---> RRC_gNB]\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - - if (ul_dcch_msg->message.choice.c1->present == NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete) { - if (ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->criticalExtensions.present == - NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete) - rrc_gNB_process_RRCReconfigurationComplete( - ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); - } - - rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); - - break; - - case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete: - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing NR_RRCSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); - break; - } - - LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC SetupComplete\n"); - MSC_LOG_RX_MESSAGE( - MSC_RRC_GNB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" NR_RRCSetupComplete UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(RRCSetupComplete) ---> RRC_gNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.present == - NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete) { - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value != NULL) { - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2) { - // ng-5G-S-TMSI-Part2 BIT STRING (SIZE (9)) - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size != 2) { - LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu", - (long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> - criticalExtensions.choice.rrcSetupComplete-> - ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size); - return -1; - } - - if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 != 0) { - ue_context_p->ue_context.ng_5G_S_TMSI_Part2 = - BIT_STRING_to_uint16(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> - criticalExtensions.choice.rrcSetupComplete-> - ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2); - } - - /* TODO */ - } else if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI) { - // NG-5G-S-TMSI ::= BIT STRING (SIZE (48)) - if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. - rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size != 6) { - LOG_E(NR_RRC, "wrong ng_5G_S_TMSI size, expected 6, provided %lu", - (long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> - criticalExtensions.choice.rrcSetupComplete-> - ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size); - return -1; - } - - uint64_t fiveg_s_TMSI = bitStr_to_uint64(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> - criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI); - LOG_I(NR_RRC, "Received rrcSetupComplete, 5g_s_TMSI: 0x%lX, amf_set_id: 0x%lX(%ld), amf_pointer: 0x%lX(%ld), 5g TMSI: 0x%X \n", - fiveg_s_TMSI, fiveg_s_TMSI >> 38, fiveg_s_TMSI >> 38, - (fiveg_s_TMSI >> 32) & 0x3F, (fiveg_s_TMSI >> 32) & 0x3F, - (uint32_t)fiveg_s_TMSI); - if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) { - ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38; - ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F; - ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI; - } - } - } - - rrc_gNB_process_RRCSetupComplete( - ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.rrcSetupComplete); - LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" UE State = RRC_CONNECTED \n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - } - - ue_context_p->ue_context.ue_release_timer = 0; - break; - case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete: - // to avoid segmentation fault - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing securityModeComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); - break; - } - - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" received securityModeComplete on UL-DCCH %d from UE\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH); - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(securityModeComplete) ---> RRC_eNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); - } - - rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); - //rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); - break; - - case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: - if(!ue_context_p) { - LOG_I(NR_RRC, "Processing ueCapabilityInformation UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); - break; - } - - LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] NR_RRC UECapablility Information\n"); - MSC_LOG_RX_MESSAGE( - MSC_RRC_GNB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" ueCapabilityInformation UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" received ueCapabilityInformation on UL-DCCH %d from UE\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH); - LOG_D(RRC, + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(UECapabilityInformation) ---> RRC_eNB\n", + "(RRCSetupComplete) ---> RRC_gNB\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), DCCH, sdu_sizeP); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); - } - LOG_I(NR_RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); - int eutra_index = -1; - if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present == - NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) { - for(i = 0;i < ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count; i++){ - if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_nr){ - if(ue_context_p->ue_context.UE_Capability_nr){ - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); - ue_context_p->ue_context.UE_Capability_nr = 0; - } + if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.present == + NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete) { + if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. + rrcSetupComplete->ng_5G_S_TMSI_Value != NULL) { + if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. + rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2) { + // ng-5G-S-TMSI-Part2 BIT STRING (SIZE (9)) + if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. + rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size != 2) { + LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu", + (long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> + criticalExtensions.choice.rrcSetupComplete-> + ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size); + return -1; + } - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_NR_Capability, - (void**)&ue_context_p->ue_context.UE_Capability_nr, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, - 0,0); - if(LOG_DEBUGFLAG(DEBUG_ASN1)){ - xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); - } + if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 != 0) { + ue_context_p->ue_context.ng_5G_S_TMSI_Part2 = + BIT_STRING_to_uint16(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> + criticalExtensions.choice.rrcSetupComplete-> + ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2); + } - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ - LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); - ue_context_p->ue_context.UE_Capability_nr = 0; - } + /* TODO */ + } else if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. + rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI) { + // NG-5G-S-TMSI ::= BIT STRING (SIZE (48)) + if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. + rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size != 6) { + LOG_E(NR_RRC, "wrong ng_5G_S_TMSI size, expected 6, provided %lu", + (long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> + criticalExtensions.choice.rrcSetupComplete-> + ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size); + return -1; + } - ue_context_p->ue_context.UE_Capability_size = - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; - if(eutra_index != -1){ - LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n"); - exit(1); - } - eutra_index = i; - } + uint64_t fiveg_s_TMSI = bitStr_to_uint64(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> + criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI); + LOG_I(NR_RRC, "Received rrcSetupComplete, 5g_s_TMSI: 0x%lX, amf_set_id: 0x%lX(%ld), amf_pointer: 0x%lX(%ld), 5g TMSI: 0x%X \n", + fiveg_s_TMSI, fiveg_s_TMSI >> 38, fiveg_s_TMSI >> 38, + (fiveg_s_TMSI >> 32) & 0x3F, (fiveg_s_TMSI >> 32) & 0x3F, + (uint32_t)fiveg_s_TMSI); + if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) { + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38; + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F; + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI; + } + } + } - if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_eutra_nr){ - if(ue_context_p->ue_context.UE_Capability_MRDC){ - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); - ue_context_p->ue_context.UE_Capability_MRDC = 0; - } - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_MRDC_Capability, - (void**)&ue_context_p->ue_context.UE_Capability_MRDC, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, - 0,0); - - if(LOG_DEBUGFLAG(DEBUG_ASN1)){ - xer_fprint(stdout,&asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); - } - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ - LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); - ue_context_p->ue_context.UE_Capability_MRDC = 0; - } - ue_context_p->ue_context.UE_MRDC_Capability_size = - ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; - } - - if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == - NR_RAT_Type_eutra){ - //TODO - } - } - - if(eutra_index == -1) - break; - } - - rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); - break; - - default: - break; + rrc_gNB_process_RRCSetupComplete( + ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.rrcSetupComplete); + LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" UE State = RRC_CONNECTED \n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); } + + ue_context_p->ue_context.ue_release_timer = 0; + break; + case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete: + // to avoid segmentation fault + if(!ue_context_p) { + LOG_I(NR_RRC, "Processing securityModeComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; + } + + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" received securityModeComplete on UL-DCCH %d from UE\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH); + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(securityModeComplete) ---> RRC_eNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); + } + + rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); + //rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + break; + + case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: + if(!ue_context_p) { + LOG_I(NR_RRC, "Processing ueCapabilityInformation UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; + } + + LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] NR_RRC UECapablility Information\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" ueCapabilityInformation UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" received ueCapabilityInformation on UL-DCCH %d from UE\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH); + LOG_D(RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(UECapabilityInformation) ---> RRC_eNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); + } + LOG_I(NR_RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); + int eutra_index = -1; + + if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present == + NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) { + for(i = 0;i < ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count; i++){ + if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_nr){ + if(ue_context_p->ue_context.UE_Capability_nr){ + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + ue_context_p->ue_context.UE_Capability_nr = 0; + } + + dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_NR_Capability, + (void**)&ue_context_p->ue_context.UE_Capability_nr, + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, + 0,0); + if(LOG_DEBUGFLAG(DEBUG_ASN1)){ + xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + } + + if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ + LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + ue_context_p->ue_context.UE_Capability_nr = 0; + } + + ue_context_p->ue_context.UE_Capability_size = + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + if(eutra_index != -1){ + LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n"); + exit(1); + } + eutra_index = i; + } + + if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_eutra_nr){ + if(ue_context_p->ue_context.UE_Capability_MRDC){ + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + ue_context_p->ue_context.UE_Capability_MRDC = 0; + } + dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_MRDC_Capability, + (void**)&ue_context_p->ue_context.UE_Capability_MRDC, + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, + 0,0); + + if(LOG_DEBUGFLAG(DEBUG_ASN1)){ + xer_fprint(stdout,&asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + } + + if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ + LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + ue_context_p->ue_context.UE_Capability_MRDC = 0; + } + ue_context_p->ue_context.UE_MRDC_Capability_size = + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + } + + if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_eutra){ + //TODO + } + } + + if(eutra_index == -1) + break; + } + + rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + break; + + default: + break; } - return 0; + } + return 0; +} + +void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m) +{ + gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP]; + rrc_remove_nsa_user(rrc, m->rnti); +} + +void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC_dc_overall_timeout_t *m) +{ + gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP]; + rrc_remove_nsa_user(rrc, m->rnti); +} + +void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { + MessageDef *msg; + + /* send a tick to x2ap */ + if (is_x2ap_enabled()){ + msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS); + itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg); + } } ///---------------------------------------------------------------------------------------------------------------/// @@ -1278,7 +1280,7 @@ void *rrc_gnb_task(void *args_p) { /* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */ if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS) - LOG_I(NR_RRC,"Received message %s\n",msg_name_p); + LOG_I(NR_RRC,"Received message %s\n",msg_name_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -1309,9 +1311,9 @@ void *rrc_gnb_task(void *args_p) { NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); if (NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= CCCH_SDU_SIZE) { - LOG_I(NR_RRC, "CCCH message has size %d > %d\n", - NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,CCCH_SDU_SIZE); - break; + LOG_I(NR_RRC, "CCCH message has size %d > %d\n", + NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,CCCH_SDU_SIZE); + break; } nr_rrc_gNB_decode_ccch(&ctxt, @@ -1336,7 +1338,6 @@ void *rrc_gnb_task(void *args_p) { NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, NR_RRC_DCCH_DATA_IND(msg_p).sdu_p, NR_RRC_DCCH_DATA_IND(msg_p).sdu_size); - break; /* @@ -1410,6 +1411,9 @@ void *rrc_gnb_task(void *args_p) { LOG_I(NR_RRC, "Handling of reconfiguration complete message at RRC gNB is pending \n"); break; + case NGAP_INITIAL_CONTEXT_SETUP_REQ: + rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p, msg_name_p, instance); + case X2AP_ENDC_SGNB_RELEASE_REQUEST: LOG_I(NR_RRC, "Received ENDC sgNB release request from X2AP \n"); rrc_gNB_process_release_request(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_RELEASE_REQUEST(msg_p)); @@ -1424,10 +1428,6 @@ void *rrc_gnb_task(void *args_p) { /* nothing to do? */ break; - case NGAP_INITIAL_CONTEXT_SETUP_REQ: - rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p, msg_name_p, instance); - break; - default: LOG_E(NR_RRC, "[gNB %d] Received unexpected message %s\n", instance, msg_name_p); break; @@ -1439,15 +1439,6 @@ void *rrc_gnb_task(void *args_p) { } } -void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) -{ - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_GNB, RRC_SUBFRAME_PROCESS); - RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt; - RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; - itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p); -} - //----------------------------------------------------------------------------- void rrc_gNB_generate_SecurityModeCommand( @@ -1491,15 +1482,15 @@ rrc_gNB_generate_SecurityModeCommand( LOG_I(NR_RRC,"calling rrc_data_req :securityModeCommand\n"); #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM,size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM,size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); #else nr_rrc_data_req(ctxt_pP, DCCH, @@ -1548,15 +1539,15 @@ rrc_gNB_generate_UECapabilityEnquiry( rrc_gNB_mui, size); #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); #else nr_rrc_data_req( ctxt_pP, @@ -1628,3 +1619,11 @@ rrc_gNB_generate_RRCConnectionRelease( PDCP_TRANSMISSION_MODE_CONTROL); } } +void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) +{ + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_GNB, RRC_SUBFRAME_PROCESS); + RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt; + RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; + itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p); +} diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 3d236859cd..1d0cfef89c 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -66,15 +66,15 @@ get_next_ue_initial_id( ) //------------------------------------------------------------------------------ { - static uint16_t ue_initial_id[NUMBER_OF_gNB_MAX]; + static uint16_t ue_initial_id[NUMBER_OF_gNB_MAX]; + ue_initial_id[mod_id]++; + + /* Never use UE_INITIAL_ID_INVALID this is the invalid id! */ + if (ue_initial_id[mod_id] == UE_INITIAL_ID_INVALID) { ue_initial_id[mod_id]++; + } - /* Never use UE_INITIAL_ID_INVALID this is the invalid id! */ - if (ue_initial_id[mod_id] == UE_INITIAL_ID_INVALID) { - ue_initial_id[mod_id]++; - } - - return ue_initial_id[mod_id]; + return ue_initial_id[mod_id]; } //------------------------------------------------------------------------------ @@ -90,11 +90,11 @@ rrc_gNB_NGAP_get_ue_ids( ) //------------------------------------------------------------------------------ { - rrc_ue_ngap_ids_t *result = NULL; + rrc_ue_ngap_ids_t *result = NULL; - /* TODO */ + /* TODO */ - return result; + return result; } //------------------------------------------------------------------------------ @@ -106,14 +106,14 @@ rrc_gNB_get_ue_context_from_ngap_ids( ) //------------------------------------------------------------------------------ { - rrc_ue_ngap_ids_t *temp = NULL; - temp = rrc_gNB_NGAP_get_ue_ids(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instanceP)], ue_initial_idP, gNB_ue_ngap_idP); + rrc_ue_ngap_ids_t *temp = NULL; + temp = rrc_gNB_NGAP_get_ue_ids(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instanceP)], ue_initial_idP, gNB_ue_ngap_idP); - if (temp != NULL) { - return rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instanceP)], temp->ue_rnti); - } + if (temp != NULL) { + return rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instanceP)], temp->ue_rnti); + } - return NULL; + return NULL; } //------------------------------------------------------------------------------ @@ -125,49 +125,50 @@ nr_rrc_pdcp_config_security( ) //------------------------------------------------------------------------------ { - NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; - pdcp_t *pdcp_p = NULL; - static int print_keys= 1; - hashtable_rc_t h_rc; - hash_key_t key; + NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; + (void)SRB_configList; + uint8_t *kRRCenc = NULL; + uint8_t *kRRCint = NULL; + uint8_t *kUPenc = NULL; + pdcp_t *pdcp_p = NULL; + static int print_keys= 1; + hashtable_rc_t h_rc; + hash_key_t key; #ifndef PHYSIM - /* Derive the keys from kgnb */ - if (SRB_configList != NULL) { - derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kgnb, - &kUPenc); - } + /* Derive the keys from kgnb */ + if (SRB_configList != NULL) { + derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, + ue_context_pP->ue_context.kgnb, + &kUPenc); + } - derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kgnb, - &kRRCenc); - derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kgnb, - &kRRCint); + derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, + ue_context_pP->ue_context.kgnb, + &kRRCenc); + derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, + ue_context_pP->ue_context.kgnb, + &kRRCint); #endif - if (!IS_SOFTMODEM_IQPLAYER) { - SET_LOG_DUMP(DEBUG_SECURITY) ; + if (!IS_SOFTMODEM_IQPLAYER) { + SET_LOG_DUMP(DEBUG_SECURITY) ; + } + + + if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) { + if (print_keys == 1 ) { + print_keys =0; + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, ue_context_pP->ue_context.kgnb, 32,"\nKgNB:" ); + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 32,"\nKRRCenc:" ); + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 32,"\nKRRCint:" ); } + } + key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); - if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) { - if (print_keys == 1 ) { - print_keys =0; - LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, ue_context_pP->ue_context.kgnb, 32,"\nKgNB:" ); - LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 32,"\nKRRCenc:" ); - LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 32,"\nKRRCint:" ); - } - } - - key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES); - h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); - - if (h_rc == HASH_TABLE_OK) { - pdcp_config_set_security( + if (h_rc == HASH_TABLE_OK) { + pdcp_config_set_security( ctxt_pP, pdcp_p, DCCH, @@ -179,12 +180,12 @@ nr_rrc_pdcp_config_security( kRRCenc, kRRCint, kUPenc); - } else { - LOG_E(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT"Could not get PDCP instance for SRB DCCH %u\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH); - } + } else { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT"Could not get PDCP instance for SRB DCCH %u\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH); + } } //------------------------------------------------------------------------------ @@ -199,111 +200,111 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ( ) //------------------------------------------------------------------------------ { - // gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - MessageDef *message_p = NULL; - rrc_ue_ngap_ids_t *rrc_ue_ngap_ids_p = NULL; - // hashtable_rc_t h_rc; + // gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; + MessageDef *message_p = NULL; + rrc_ue_ngap_ids_t *rrc_ue_ngap_ids_p = NULL; + // hashtable_rc_t h_rc; - message_p = itti_alloc_new_message(TASK_RRC_GNB, NGAP_NAS_FIRST_REQ); - memset(&message_p->ittiMsg.ngap_nas_first_req, 0, sizeof(ngap_nas_first_req_t)); - ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id(ctxt_pP->module_id); - NGAP_NAS_FIRST_REQ(message_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id; - rrc_ue_ngap_ids_p = malloc(sizeof(rrc_ue_ngap_ids_t)); - rrc_ue_ngap_ids_p->ue_initial_id = ue_context_pP->ue_context.ue_initial_id; - rrc_ue_ngap_ids_p->gNB_ue_ngap_id = UE_INITIAL_ID_INVALID; - rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rnti; + message_p = itti_alloc_new_message(TASK_RRC_GNB, NGAP_NAS_FIRST_REQ); + memset(&message_p->ittiMsg.ngap_nas_first_req, 0, sizeof(ngap_nas_first_req_t)); + ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id(ctxt_pP->module_id); + NGAP_NAS_FIRST_REQ(message_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id; + rrc_ue_ngap_ids_p = malloc(sizeof(rrc_ue_ngap_ids_t)); + rrc_ue_ngap_ids_p->ue_initial_id = ue_context_pP->ue_context.ue_initial_id; + rrc_ue_ngap_ids_p->gNB_ue_ngap_id = UE_INITIAL_ID_INVALID; + rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rnti; - // h_rc = hashtable_insert(RC.nrrrc[ctxt_pP->module_id]->initial_id2_s1ap_ids, - // (hash_key_t)ue_context_pP->ue_context.ue_initial_id, - // rrc_ue_s1ap_ids_p); + // h_rc = hashtable_insert(RC.nrrrc[ctxt_pP->module_id]->initial_id2_s1ap_ids, + // (hash_key_t)ue_context_pP->ue_context.ue_initial_id, + // rrc_ue_s1ap_ids_p); - // if (h_rc != HASH_TABLE_OK) { - // LOG_E(S1AP, "[eNB %d] Error while hashtable_insert in initial_id2_s1ap_ids ue_initial_id %u\n", - // ctxt_pP->module_id, - // ue_context_pP->ue_context.ue_initial_id); - // } + // if (h_rc != HASH_TABLE_OK) { + // LOG_E(S1AP, "[eNB %d] Error while hashtable_insert in initial_id2_s1ap_ids ue_initial_id %u\n", + // ctxt_pP->module_id, + // ue_context_pP->ue_context.ue_initial_id); + // } - /* Assume that cause is coded in the same way in RRC and NGap, just check that the value is in NGap range */ - AssertFatal(ue_context_pP->ue_context.establishment_cause < NGAP_RRC_CAUSE_LAST, - "Establishment cause invalid (%jd/%d) for gNB %d!", - ue_context_pP->ue_context.establishment_cause, - NGAP_RRC_CAUSE_LAST, - ctxt_pP->module_id); - NGAP_NAS_FIRST_REQ(message_p).establishment_cause = ue_context_pP->ue_context.establishment_cause; - - /* Forward NAS message */ - NGAP_NAS_FIRST_REQ(message_p).nas_pdu.buffer = rrcSetupComplete->dedicatedNAS_Message.buf; - NGAP_NAS_FIRST_REQ(message_p).nas_pdu.length = rrcSetupComplete->dedicatedNAS_Message.size; - // extract_imsi(NGAP_NAS_FIRST_REQ (message_p).nas_pdu.buffer, - // NGAP_NAS_FIRST_REQ (message_p).nas_pdu.length, - // ue_context_pP); + /* Assume that cause is coded in the same way in RRC and NGap, just check that the value is in NGap range */ + AssertFatal(ue_context_pP->ue_context.establishment_cause < NGAP_RRC_CAUSE_LAST, + "Establishment cause invalid (%jd/%d) for gNB %d!", + ue_context_pP->ue_context.establishment_cause, + NGAP_RRC_CAUSE_LAST, + ctxt_pP->module_id); + NGAP_NAS_FIRST_REQ(message_p).establishment_cause = ue_context_pP->ue_context.establishment_cause; - /* Fill UE identities with available information */ - NGAP_NAS_FIRST_REQ(message_p).ue_identity.presenceMask = NGAP_UE_IDENTITIES_NONE; - /* Fill s-TMSI */ - NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.amf_set_id = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id; - NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.amf_pointer = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer; - NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.m_tmsi = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi; + /* Forward NAS message */ + NGAP_NAS_FIRST_REQ(message_p).nas_pdu.buffer = rrcSetupComplete->dedicatedNAS_Message.buf; + NGAP_NAS_FIRST_REQ(message_p).nas_pdu.length = rrcSetupComplete->dedicatedNAS_Message.size; + // extract_imsi(NGAP_NAS_FIRST_REQ (message_p).nas_pdu.buffer, + // NGAP_NAS_FIRST_REQ (message_p).nas_pdu.length, + // ue_context_pP); - /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */ - int selected_plmn_identity = rrcSetupComplete->selectedPLMN_Identity - 1; - NGAP_NAS_FIRST_REQ(message_p).selected_plmn_identity = selected_plmn_identity; + /* Fill UE identities with available information */ + NGAP_NAS_FIRST_REQ(message_p).ue_identity.presenceMask = NGAP_UE_IDENTITIES_NONE; + /* Fill s-TMSI */ + NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.amf_set_id = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id; + NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.amf_pointer = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer; + NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.m_tmsi = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi; - if (rrcSetupComplete->registeredAMF != NULL) { - NR_RegisteredAMF_t *r_amf = rrcSetupComplete->registeredAMF; - NGAP_NAS_FIRST_REQ(message_p).ue_identity.presenceMask |= NGAP_UE_IDENTITIES_guami; + /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */ + int selected_plmn_identity = rrcSetupComplete->selectedPLMN_Identity - 1; + NGAP_NAS_FIRST_REQ(message_p).selected_plmn_identity = selected_plmn_identity; - if (r_amf->plmn_Identity != NULL) { - if ((r_amf->plmn_Identity->mcc != NULL) && (r_amf->plmn_Identity->mcc->list.count > 0)) { - /* Use first indicated PLMN MCC if it is defined */ - NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc = *r_amf->plmn_Identity->mcc->list.array[selected_plmn_identity]; - LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", - ctxt_pP->module_id, - NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mcc, - ue_context_pP->ue_context.rnti); - } + if (rrcSetupComplete->registeredAMF != NULL) { + NR_RegisteredAMF_t *r_amf = rrcSetupComplete->registeredAMF; + NGAP_NAS_FIRST_REQ(message_p).ue_identity.presenceMask |= NGAP_UE_IDENTITIES_guami; - if (r_amf->plmn_Identity->mnc.list.count > 0) { - /* Use first indicated PLMN MNC if it is defined */ - NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc = *r_amf->plmn_Identity->mnc.list.array[selected_plmn_identity]; - LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", - ctxt_pP->module_id, - NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mnc, - ue_context_pP->ue_context.rnti); - } - } else { - /* TODO */ - } + if (r_amf->plmn_Identity != NULL) { + if ((r_amf->plmn_Identity->mcc != NULL) && (r_amf->plmn_Identity->mcc->list.count > 0)) { + /* Use first indicated PLMN MCC if it is defined */ + NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc = *r_amf->plmn_Identity->mcc->list.array[selected_plmn_identity]; + LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", + ctxt_pP->module_id, + NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mcc, + ue_context_pP->ue_context.rnti); + } - /* amf_Identifier */ - uint32_t amf_Id = BIT_STRING_to_uint32(&r_amf->amf_Identifier); - NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id = amf_Id >> 16; - NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id; - NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer; - - ue_context_pP->ue_context.ue_guami.mcc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc; - ue_context_pP->ue_context.ue_guami.mnc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc; - ue_context_pP->ue_context.ue_guami.mnc_len = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc_len; - ue_context_pP->ue_context.ue_guami.amf_region_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id; - ue_context_pP->ue_context.ue_guami.amf_set_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id; - ue_context_pP->ue_context.ue_guami.amf_pointer = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer; - - MSC_LOG_TX_MESSAGE(MSC_NGAP_GNB, - MSC_NGAP_AMF, - (const char *)&message_p->ittiMsg.ngap_nas_first_req, - sizeof(ngap_nas_first_req_t), - MSC_AS_TIME_FMT" NGAP_NAS_FIRST_REQ gNB %u UE %x", - MSC_AS_TIME_ARGS(ctxt_pP), - ctxt_pP->module_id, - ctxt_pP->rnti); - LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n", - ctxt_pP->module_id, - NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_set_id, - NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_region_id, - ue_context_pP->ue_context.rnti); + if (r_amf->plmn_Identity->mnc.list.count > 0) { + /* Use first indicated PLMN MNC if it is defined */ + NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc = *r_amf->plmn_Identity->mnc.list.array[selected_plmn_identity]; + LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", + ctxt_pP->module_id, + NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mnc, + ue_context_pP->ue_context.rnti); + } + } else { + /* TODO */ } - itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, message_p); + /* amf_Identifier */ + uint32_t amf_Id = BIT_STRING_to_uint32(&r_amf->amf_Identifier); + NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id = amf_Id >> 16; + NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id; + NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer; + + ue_context_pP->ue_context.ue_guami.mcc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc; + ue_context_pP->ue_context.ue_guami.mnc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc; + ue_context_pP->ue_context.ue_guami.mnc_len = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc_len; + ue_context_pP->ue_context.ue_guami.amf_region_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id; + ue_context_pP->ue_context.ue_guami.amf_set_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id; + ue_context_pP->ue_context.ue_guami.amf_pointer = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer; + + MSC_LOG_TX_MESSAGE(MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)&message_p->ittiMsg.ngap_nas_first_req, + sizeof(ngap_nas_first_req_t), + MSC_AS_TIME_FMT" NGAP_NAS_FIRST_REQ gNB %u UE %x", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt_pP->module_id, + ctxt_pP->rnti); + LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n", + ctxt_pP->module_id, + NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_set_id, + NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_region_id, + ue_context_pP->ue_context.rnti); + } + + itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, message_p); } //------------------------------------------------------------------------------ @@ -315,69 +316,69 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( ) //------------------------------------------------------------------------------ { - uint16_t ue_initial_id; - uint32_t gNB_ue_ngap_id; - rrc_gNB_ue_context_t *ue_context_p = NULL; - protocol_ctxt_t ctxt; + uint16_t ue_initial_id; + uint32_t gNB_ue_ngap_id; + rrc_gNB_ue_context_t *ue_context_p = NULL; + protocol_ctxt_t ctxt; - ue_initial_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id; - gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).gNB_ue_ngap_id; + ue_initial_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id; + gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).gNB_ue_ngap_id; - ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); - LOG_I(NR_RRC, "[gNB %d] Received %s: ue_initial_id %d, gNB_ue_ngap_id %d \n", - instance, msg_name, ue_initial_id, gNB_ue_ngap_id); + ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); + LOG_I(NR_RRC, "[gNB %d] Received %s: ue_initial_id %d, gNB_ue_ngap_id %d \n", + instance, msg_name, ue_initial_id, gNB_ue_ngap_id); - if (ue_context_p == NULL) { - /* Can not associate this message to an UE index, send a failure to NGAP and discard it! */ - MessageDef *msg_fail_p = NULL; - LOG_W(NR_RRC, "[gNB %d] In NGAP_INITIAL_CONTEXT_SETUP_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, gNB_ue_ngap_id); - msg_fail_p = itti_alloc_new_message (TASK_RRC_GNB, NGAP_INITIAL_CONTEXT_SETUP_FAIL); - NGAP_INITIAL_CONTEXT_SETUP_FAIL (msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); - return (-1); - } else { - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); - ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).gNB_ue_ngap_id; - ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id; - - /* NAS PDU */ - if (ue_context_p->ue_context.nas_pdu_flag == 1) { - ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length; - ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer; - } - - /* TODO security */ - rrc_gNB_process_security(&ctxt, ue_context_p, &(NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_capabilities)); - - uint8_t send_security_mode_command = TRUE; + if (ue_context_p == NULL) { + /* Can not associate this message to an UE index, send a failure to NGAP and discard it! */ + MessageDef *msg_fail_p = NULL; + LOG_W(NR_RRC, "[gNB %d] In NGAP_INITIAL_CONTEXT_SETUP_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, gNB_ue_ngap_id); + msg_fail_p = itti_alloc_new_message (TASK_RRC_GNB, NGAP_INITIAL_CONTEXT_SETUP_FAIL); + NGAP_INITIAL_CONTEXT_SETUP_FAIL (msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; + // TODO add failure cause when defined! + itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); + return (-1); + } else { + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).gNB_ue_ngap_id; + ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id; + + /* NAS PDU */ + if (ue_context_p->ue_context.nas_pdu_flag == 1) { + ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length; + ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer; + } + + /* TODO security */ + rrc_gNB_process_security(&ctxt, ue_context_p, &(NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_capabilities)); + + uint8_t send_security_mode_command = TRUE; + + nr_rrc_pdcp_config_security( + &ctxt, + ue_context_p, + send_security_mode_command); + + if (send_security_mode_command) { + rrc_gNB_generate_SecurityModeCommand (&ctxt, ue_context_p); + send_security_mode_command = FALSE; nr_rrc_pdcp_config_security( &ctxt, ue_context_p, send_security_mode_command); - - if (send_security_mode_command) { - rrc_gNB_generate_SecurityModeCommand (&ctxt, ue_context_p); - send_security_mode_command = FALSE; - - nr_rrc_pdcp_config_security( - &ctxt, - ue_context_p, - send_security_mode_command); - } else { - /* rrc_gNB_generate_UECapabilityEnquiry */ - rrc_gNB_generate_UECapabilityEnquiry(&ctxt, ue_context_p); - } - - // in case, send the S1SP initial context response if it is not sent with the attach complete message - if (ue_context_p->ue_context.Status == NR_RRC_RECONFIGURED) { - LOG_I(NR_RRC, "Sending rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause); - rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(&ctxt,ue_context_p); - } - - return 0; + } else { + /* rrc_gNB_generate_UECapabilityEnquiry */ + rrc_gNB_generate_UECapabilityEnquiry(&ctxt, ue_context_p); } + + // in case, send the S1SP initial context response if it is not sent with the attach complete message + if (ue_context_p->ue_context.Status == NR_RRC_RECONFIGURED) { + LOG_I(NR_RRC, "Sending rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause); + rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(&ctxt,ue_context_p); + } + + return 0; + } } //------------------------------------------------------------------------------ diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index d1e78375ea..197c3f1f87 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -56,6 +56,11 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco int initial_csi_index) { AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n"); AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n"); + + if(servingcellconfigcommon->ssb_PositionsInBurst->present !=2) + AssertFatal(1==0,"Currenrly implemented only for medium size SSB bitmap\n"); + uint8_t bitmap = servingcellconfigcommon->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]; + memset(secondaryCellGroup,0,sizeof(NR_CellGroupConfig_t)); secondaryCellGroup->cellGroupId = scg_id; NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); @@ -242,9 +247,29 @@ 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; -#if 0 + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList)); + int n_ssb = 0; + NR_TCI_State_t *tcic[8]; + for (int i=0;i<8;i++) { + if ((bitmap>>(7-i))&0x01){ + tcic[i]=calloc(1,sizeof(*tcic[i])); + tcic[i]->tci_StateId=n_ssb; + tcic[i]->qcl_Type1.cell=NULL; + tcic[i]->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcic[i]->qcl_Type1.bwp_Id)); + *tcic[i]->qcl_Type1.bwp_Id=1; + tcic[i]->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; + tcic[i]->qcl_Type1.referenceSignal.choice.ssb = i; + tcic[i]->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcic[i]); + n_ssb++; + } + } + + +#if 0 + NR_TCI_State_t*tci0=calloc(1,sizeof(*tci0)); tci0->tci_StateId=0; tci0->qcl_Type1.cell=NULL; @@ -325,85 +350,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco tci7->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci7); - NR_TCI_State_t*tci8=calloc(1,sizeof(*tci8)); - tci8->tci_StateId=8; - tci8->qcl_Type1.cell=NULL; - tci8->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci8->qcl_Type1.bwp_Id)); - *tci8->qcl_Type1.bwp_Id=1; - tci8->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tci8->qcl_Type1.referenceSignal.choice.ssb = 0; - tci8->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci8); - - NR_TCI_State_t*tci9=calloc(1,sizeof(*tci9)); - tci9->tci_StateId=9; - tci9->qcl_Type1.cell=NULL; - tci9->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci9->qcl_Type1.bwp_Id)); - *tci9->qcl_Type1.bwp_Id=1; - tci9->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tci9->qcl_Type1.referenceSignal.choice.ssb = 1; - tci9->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci9); - - NR_TCI_State_t*tci10=calloc(1,sizeof(*tci10)); - tci10->tci_StateId=10; - tci10->qcl_Type1.cell=NULL; - tci10->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci10->qcl_Type1.bwp_Id)); - *tci10->qcl_Type1.bwp_Id=1; - tci10->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tci10->qcl_Type1.referenceSignal.choice.ssb = 2; - tci10->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci10); - - NR_TCI_State_t*tci11=calloc(1,sizeof(*tci11)); - tci11->tci_StateId=11; - tci11->qcl_Type1.cell=NULL; - tci11->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci11->qcl_Type1.bwp_Id)); - *tci11->qcl_Type1.bwp_Id=1; - tci11->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tci11->qcl_Type1.referenceSignal.choice.ssb = 3; - tci11->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci11); - - NR_TCI_State_t*tci12=calloc(1,sizeof(*tci12)); - tci12->tci_StateId=12; - tci12->qcl_Type1.cell=NULL; - tci12->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci12->qcl_Type1.bwp_Id)); - *tci12->qcl_Type1.bwp_Id=1; - tci12->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tci12->qcl_Type1.referenceSignal.choice.ssb = 4; - tci12->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci12); - - NR_TCI_State_t*tci13=calloc(1,sizeof(*tci13)); - tci13->tci_StateId=13; - tci13->qcl_Type1.cell=NULL; - tci13->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci13->qcl_Type1.bwp_Id)); - *tci13->qcl_Type1.bwp_Id=1; - tci13->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tci13->qcl_Type1.referenceSignal.choice.ssb = 5; - tci13->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci13); - - NR_TCI_State_t*tci14=calloc(1,sizeof(*tci14)); - tci14->tci_StateId=14; - tci14->qcl_Type1.cell=NULL; - tci14->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci14->qcl_Type1.bwp_Id)); - *tci14->qcl_Type1.bwp_Id=1; - tci14->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tci14->qcl_Type1.referenceSignal.choice.ssb = 6; - tci14->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci14); - - NR_TCI_State_t*tci15=calloc(1,sizeof(*tci15)); - tci15->tci_StateId=15; - tci15->qcl_Type1.cell=NULL; - tci15->qcl_Type1.bwp_Id=calloc(1,sizeof(*tci15->qcl_Type1.bwp_Id)); - *tci15->qcl_Type1.bwp_Id=1; - tci15->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tci15->qcl_Type1.referenceSignal.choice.ssb = 7; - tci15->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tci15); #endif secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToReleaseList=NULL; @@ -485,9 +431,11 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco coreset->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset->tci_StatesPDCCH_ToAddList)); NR_TCI_StateId_t *tci[8]; for (int i=0;i<8;i++) { - tci[i]=calloc(1,sizeof(*tci[i])); - *tci[i] = i; - ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]); + if ((bitmap>>(7-i))&0x01){ + tci[i]=calloc(1,sizeof(*tci[i])); + *tci[i] = i; + ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]); + } } coreset->tci_StatesPDCCH_ToReleaseList = NULL; coreset->tci_PresentInDCI = NULL; @@ -616,7 +564,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition)); *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=NULL; + //bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList)); + #if 0 bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList)); @@ -699,88 +649,27 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco tcid7->qcl_Type1.referenceSignal.choice.csi_rs = 30; tcid7->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeA; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid7); - - NR_TCI_State_t*tcid8=calloc(1,sizeof(*tcid8)); - tcid8->tci_StateId=8; - tcid8->qcl_Type1.cell=NULL; - tcid8->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid8->qcl_Type1.bwp_Id)); - *tcid8->qcl_Type1.bwp_Id=1; - tcid8->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tcid8->qcl_Type1.referenceSignal.choice.ssb = 0; - tcid8->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid8); - - NR_TCI_State_t*tcid9=calloc(1,sizeof(*tcid9)); - tcid9->tci_StateId=9; - tcid9->qcl_Type1.cell=NULL; - tcid9->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid9->qcl_Type1.bwp_Id)); - *tcid9->qcl_Type1.bwp_Id=1; - tcid9->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tcid9->qcl_Type1.referenceSignal.choice.ssb = 1; - tcid9->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid9); - - NR_TCI_State_t*tcid10=calloc(1,sizeof(*tcid10)); - tcid10->tci_StateId=10; - tcid10->qcl_Type1.cell=NULL; - tcid10->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid10->qcl_Type1.bwp_Id)); - *tcid10->qcl_Type1.bwp_Id=1; - tcid10->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tcid10->qcl_Type1.referenceSignal.choice.ssb = 2; - tcid10->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid10); - - NR_TCI_State_t*tcid11=calloc(1,sizeof(*tcid11)); - tcid11->tci_StateId=11; - tcid11->qcl_Type1.cell=NULL; - tcid11->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid11->qcl_Type1.bwp_Id)); - *tcid11->qcl_Type1.bwp_Id=1; - tcid11->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tcid11->qcl_Type1.referenceSignal.choice.ssb = 3; - tcid11->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid11); - - NR_TCI_State_t*tcid12=calloc(1,sizeof(*tcid12)); - tcid12->tci_StateId=12; - tcid12->qcl_Type1.cell=NULL; - tcid12->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid12->qcl_Type1.bwp_Id)); - *tcid12->qcl_Type1.bwp_Id=1; - tcid12->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tcid12->qcl_Type1.referenceSignal.choice.ssb = 4; - tcid12->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid12); - - NR_TCI_State_t*tcid13=calloc(1,sizeof(*tcid13)); - tcid13->tci_StateId=13; - tcid13->qcl_Type1.cell=NULL; - tcid13->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid13->qcl_Type1.bwp_Id)); - *tcid13->qcl_Type1.bwp_Id=1; - tcid13->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tcid13->qcl_Type1.referenceSignal.choice.ssb = 5; - tcid13->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid13); - - NR_TCI_State_t*tcid14=calloc(1,sizeof(*tcid14)); - tcid14->tci_StateId=14; - tcid14->qcl_Type1.cell=NULL; - tcid14->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid14->qcl_Type1.bwp_Id)); - *tcid14->qcl_Type1.bwp_Id=1; - tcid14->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tcid14->qcl_Type1.referenceSignal.choice.ssb = 6; - tcid14->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid14); - - NR_TCI_State_t*tcid15=calloc(1,sizeof(*tcid15)); - tcid15->tci_StateId=15; - tcid15->qcl_Type1.cell=NULL; - tcid15->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid15->qcl_Type1.bwp_Id)); - *tcid15->qcl_Type1.bwp_Id=1; - tcid15->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; - tcid15->qcl_Type1.referenceSignal.choice.ssb = 7; - tcid15->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid15); #endif + + n_ssb = 0; + NR_TCI_State_t *tcid[8]; + for (int i=0;i<8;i++) { + if ((bitmap>>(7-i))&0x01){ + tcid[i]=calloc(1,sizeof(*tcid[i])); + tcid[i]->tci_StateId=n_ssb; + tcid[i]->qcl_Type1.cell=NULL; + tcid[i]->qcl_Type1.bwp_Id=calloc(1,sizeof(*tcid[i]->qcl_Type1.bwp_Id)); + *tcid[i]->qcl_Type1.bwp_Id=1; + tcid[i]->qcl_Type1.referenceSignal.present = NR_QCL_Info__referenceSignal_PR_ssb; + tcid[i]->qcl_Type1.referenceSignal.choice.ssb = i; + tcid[i]->qcl_Type1.qcl_Type=NR_QCL_Info__qcl_Type_typeC; + ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList->list,tcid[i]); + n_ssb++; + } + } + + bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToReleaseList=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->vrb_ToPRB_Interleaver=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType1; @@ -895,12 +784,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco aset->alpha=calloc(1,sizeof(*aset->alpha)); *aset->alpha=NR_Alpha_alpha1; ASN_SEQUENCE_ADD(&pusch_Config->pusch_PowerControl->p0_AlphaSets->list,aset); - pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList = calloc(1,sizeof(*pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList)); - NR_PUSCH_PathlossReferenceRS_t *pl = calloc(1,sizeof(*pl)); - pl->pusch_PathlossReferenceRS_Id=0; - pl->referenceSignal.present = NR_PUSCH_PathlossReferenceRS__referenceSignal_PR_csi_RS_Index; - pl->referenceSignal.choice.csi_RS_Index=0; - ASN_SEQUENCE_ADD(&pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList->list,pl); + pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList = NULL; pusch_Config->pusch_PowerControl->pathlossReferenceRSToReleaseList = NULL; pusch_Config->pusch_PowerControl->twoPUSCH_PC_AdjustmentStates = NULL; pusch_Config->pusch_PowerControl->deltaMCS = NULL; @@ -1058,7 +942,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pucchres2->secondHopPRB=NULL; pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs=16; + pucchres2->format.choice.format2->nrofPRBs=4; pucchres2->format.choice.format2->nrofSymbols=1; pucchres2->format.choice.format2->startingSymbolIndex=13; ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); @@ -1069,7 +953,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pucchres3->secondHopPRB=NULL; pucchres3->format.present= NR_PUCCH_Resource__format_PR_format2; pucchres3->format.choice.format2=calloc(1,sizeof(*pucchres3->format.choice.format2)); - pucchres3->format.choice.format2->nrofPRBs=16; + pucchres3->format.choice.format2->nrofPRBs=4; pucchres3->format.choice.format2->nrofSymbols=1; pucchres3->format.choice.format2->startingSymbolIndex=12; ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres3); @@ -1081,7 +965,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pucchfmt2->interslotFrequencyHopping=NULL; pucchfmt2->additionalDMRS=NULL; pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate)); - *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot15; + *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot25; pucchfmt2->nrofSlots=NULL; pucchfmt2->pi2BPSK=NULL; pucchfmt2->simultaneousHARQ_ACK_CSI=NULL; @@ -1122,12 +1006,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco p00->p0_PUCCH_Id=1; p00->p0_PUCCH_Value = 0; ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->p0_Set->list,p00); - pucch_Config->pucch_PowerControl->pathlossReferenceRSs = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->pathlossReferenceRSs)); - NR_PUCCH_PathlossReferenceRS_t *pucchPLRef=calloc(1,sizeof(*pucchPLRef)); - pucchPLRef->pucch_PathlossReferenceRS_Id=0; - pucchPLRef->referenceSignal.present = NR_PUCCH_PathlossReferenceRS__referenceSignal_PR_csi_RS_Index; - pucchPLRef->referenceSignal.choice.csi_RS_Index=0; - ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->pathlossReferenceRSs->list,pucchPLRef); + pucch_Config->pucch_PowerControl->pathlossReferenceRSs = NULL; // copy pusch_Config from dedicated initialBWP ubwp->bwp_Dedicated->pusch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pusch_Config)); @@ -1178,595 +1057,61 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pdsch_servingcellconfig->ext1->processingType2Enabled = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig=NULL; - //secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig)); - //secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->present = NR_SetupRelease_CSI_MeasConfig_PR_setup; - + secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->present = NR_SetupRelease_CSI_MeasConfig_PR_setup; NR_CSI_MeasConfig_t *csi_MeasConfig = calloc(1,sizeof(*csi_MeasConfig)); -// secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup = csi_MeasConfig; - csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList)); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup = csi_MeasConfig; - NR_NZP_CSI_RS_Resource_t *nzpres0 = calloc(1,sizeof(*nzpres0)); - nzpres0->nzp_CSI_RS_ResourceId=0; - nzpres0->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other; - nzpres0->resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(1,1); - nzpres0->resourceMapping.frequencyDomainAllocation.choice.other.size = 1; - nzpres0->resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2; - nzpres0->resourceMapping.frequencyDomainAllocation.choice.other.buf[0]=1<<2; - nzpres0->resourceMapping.nrofPorts = (n_physical_antenna_ports==1)? NR_CSI_RS_ResourceMapping__nrofPorts_p1 : NR_CSI_RS_ResourceMapping__nrofPorts_p2; - nzpres0->resourceMapping.firstOFDMSymbolInTimeDomain=7; - nzpres0->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres0->resourceMapping.cdm_Type = (n_physical_antenna_ports==1)? NR_CSI_RS_ResourceMapping__cdm_Type_noCDM : NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2; - nzpres0->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_one; - nzpres0->resourceMapping.density.choice.one=(NULL_t)0; - nzpres0->resourceMapping.freqBand.startingRB=0; - nzpres0->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres0->powerControlOffset=13; - nzpres0->powerControlOffsetSS=NULL; - nzpres0->scramblingID=40; - nzpres0->periodicityAndOffset = calloc(1,sizeof(*nzpres0->periodicityAndOffset)); - nzpres0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320; - nzpres0->periodicityAndOffset->choice.slots320 = 2; - nzpres0->qcl_InfoPeriodicCSI_RS=NULL; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres0); - - if (n_physical_antenna_ports > 1) { - NR_NZP_CSI_RS_Resource_t *nzpres2 = calloc(1,sizeof(*nzpres2)); - nzpres2->nzp_CSI_RS_ResourceId=2; - nzpres2->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres2->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres2->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres2->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres2->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=1; - nzpres2->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres2->resourceMapping.firstOFDMSymbolInTimeDomain=4; - nzpres2->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres2->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres2->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres2->resourceMapping.density.choice.three=(NULL_t)0; - nzpres2->resourceMapping.freqBand.startingRB=0; - nzpres2->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres2->powerControlOffset=0; - nzpres2->powerControlOffsetSS=calloc(1,sizeof(*nzpres2->powerControlOffsetSS)); - *nzpres2->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres2->scramblingID=40; - nzpres2->periodicityAndOffset = calloc(1,sizeof(*nzpres2->periodicityAndOffset)); - nzpres2->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres2->periodicityAndOffset->choice.slots160 = 25; - nzpres2->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres2->qcl_InfoPeriodicCSI_RS)); - *nzpres2->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres2); - - - NR_NZP_CSI_RS_Resource_t *nzpres3 = calloc(1,sizeof(*nzpres3)); - nzpres3->nzp_CSI_RS_ResourceId=3; - nzpres3->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres3->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres3->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres3->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres3->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=1; - nzpres3->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres3->resourceMapping.firstOFDMSymbolInTimeDomain=8; - nzpres3->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres3->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres3->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres3->resourceMapping.density.choice.three=(NULL_t)0; - nzpres3->resourceMapping.freqBand.startingRB=0; - nzpres3->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres3->powerControlOffset=0; - nzpres3->powerControlOffsetSS=calloc(1,sizeof(*nzpres3->powerControlOffsetSS)); - *nzpres3->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres3->scramblingID=40; - nzpres3->periodicityAndOffset = calloc(1,sizeof(*nzpres3->periodicityAndOffset)); - nzpres3->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres3->periodicityAndOffset->choice.slots160 = 25; - nzpres3->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres3->qcl_InfoPeriodicCSI_RS)); - *nzpres3->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres3); - } - if (n_physical_antenna_ports > 3) { - NR_NZP_CSI_RS_Resource_t *nzpres4 = calloc(1,sizeof(*nzpres4)); - nzpres4->nzp_CSI_RS_ResourceId=4; - nzpres4->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres4->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres4->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres4->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres4->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=1; - nzpres4->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres4->resourceMapping.firstOFDMSymbolInTimeDomain=4; - nzpres4->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres4->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres4->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres4->resourceMapping.density.choice.three=(NULL_t)0; - nzpres4->resourceMapping.freqBand.startingRB=0; - nzpres4->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres4->powerControlOffset=0; - nzpres4->powerControlOffsetSS=calloc(1,sizeof(*nzpres4->powerControlOffsetSS)); - *nzpres4->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres4->scramblingID=40; - nzpres4->periodicityAndOffset = calloc(1,sizeof(*nzpres4->periodicityAndOffset)); - nzpres4->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres4->periodicityAndOffset->choice.slots160 = 26; - nzpres4->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres4->qcl_InfoPeriodicCSI_RS)); - *nzpres4->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres4); - - NR_NZP_CSI_RS_Resource_t *nzpres5 = calloc(1,sizeof(*nzpres5)); - nzpres5->nzp_CSI_RS_ResourceId=5; - nzpres5->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres5->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres5->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres5->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres5->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=1; - nzpres5->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres5->resourceMapping.firstOFDMSymbolInTimeDomain=8; - nzpres5->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres5->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres5->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres5->resourceMapping.density.choice.three=(NULL_t)0; - nzpres5->resourceMapping.freqBand.startingRB=0; - nzpres5->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres5->powerControlOffset=0; - nzpres5->powerControlOffsetSS=calloc(1,sizeof(*nzpres5->powerControlOffsetSS)); - *nzpres5->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres5->scramblingID=40; - nzpres5->periodicityAndOffset = calloc(1,sizeof(*nzpres5->periodicityAndOffset)); - nzpres5->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres5->periodicityAndOffset->choice.slots160 = 26; - nzpres5->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres5->qcl_InfoPeriodicCSI_RS)); - *nzpres5->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres5); - } - if (n_physical_antenna_ports > 7) { - NR_NZP_CSI_RS_Resource_t *nzpres6 = calloc(1,sizeof(*nzpres6)); - nzpres6->nzp_CSI_RS_ResourceId=6; - nzpres6->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres6->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres6->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres6->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres6->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=4; - nzpres6->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres6->resourceMapping.firstOFDMSymbolInTimeDomain=4; - nzpres6->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres6->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres6->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres6->resourceMapping.density.choice.three=(NULL_t)0; - nzpres6->resourceMapping.freqBand.startingRB=0; - nzpres6->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres6->powerControlOffset=0; - nzpres6->powerControlOffsetSS=calloc(1,sizeof(*nzpres6->powerControlOffsetSS)); - *nzpres6->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres6->scramblingID=40; - nzpres6->periodicityAndOffset = calloc(1,sizeof(*nzpres6->periodicityAndOffset)); - nzpres6->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres6->periodicityAndOffset->choice.slots160 = 25; - nzpres6->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres6->qcl_InfoPeriodicCSI_RS)); - *nzpres6->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres6); - - NR_NZP_CSI_RS_Resource_t *nzpres7 = calloc(1,sizeof(*nzpres7)); - nzpres7->nzp_CSI_RS_ResourceId=7; - nzpres7->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres7->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres7->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres7->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres7->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=4; - nzpres7->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres7->resourceMapping.firstOFDMSymbolInTimeDomain=8; - nzpres7->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres7->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres7->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres7->resourceMapping.density.choice.three=(NULL_t)0; - nzpres7->resourceMapping.freqBand.startingRB=0; - nzpres7->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres7->powerControlOffset=0; - nzpres7->powerControlOffsetSS=calloc(1,sizeof(*nzpres7->powerControlOffsetSS)); - *nzpres7->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres7->scramblingID=40; - nzpres7->periodicityAndOffset = calloc(1,sizeof(*nzpres7->periodicityAndOffset)); - nzpres7->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres7->periodicityAndOffset->choice.slots160 = 25; - nzpres7->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres7->qcl_InfoPeriodicCSI_RS)); - *nzpres7->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres7); - NR_NZP_CSI_RS_Resource_t *nzpres8 = calloc(1,sizeof(*nzpres8)); - nzpres8->nzp_CSI_RS_ResourceId=8; - nzpres8->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres8->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres8->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres8->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres8->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=4; - nzpres8->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres8->resourceMapping.firstOFDMSymbolInTimeDomain=4; - nzpres8->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres8->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres8->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres8->resourceMapping.density.choice.three=(NULL_t)0; - nzpres8->resourceMapping.freqBand.startingRB=0; - nzpres8->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres8->powerControlOffset=0; - nzpres8->powerControlOffsetSS=calloc(1,sizeof(*nzpres8->powerControlOffsetSS)); - *nzpres8->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres8->scramblingID=40; - nzpres8->periodicityAndOffset = calloc(1,sizeof(*nzpres8->periodicityAndOffset)); - nzpres8->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres8->periodicityAndOffset->choice.slots160 = 26; - nzpres8->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres8->qcl_InfoPeriodicCSI_RS)); - *nzpres8->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres8); - - NR_NZP_CSI_RS_Resource_t *nzpres9 = calloc(1,sizeof(*nzpres9)); - nzpres9->nzp_CSI_RS_ResourceId=9; - nzpres9->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres9->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres9->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres9->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres9->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=4; - nzpres9->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres9->resourceMapping.firstOFDMSymbolInTimeDomain=8; - nzpres9->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres9->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres9->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres9->resourceMapping.density.choice.three=(NULL_t)0; - nzpres9->resourceMapping.freqBand.startingRB=0; - nzpres9->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres9->powerControlOffset=0; - nzpres9->powerControlOffsetSS=calloc(1,sizeof(*nzpres9->powerControlOffsetSS)); - *nzpres9->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres9->scramblingID=40; - nzpres9->periodicityAndOffset = calloc(1,sizeof(*nzpres9->periodicityAndOffset)); - nzpres9->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres9->periodicityAndOffset->choice.slots160 = 26; - nzpres9->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres9->qcl_InfoPeriodicCSI_RS)); - *nzpres9->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres9); - } - if (n_physical_antenna_ports > 15) { - NR_NZP_CSI_RS_Resource_t *nzpres10 = calloc(1,sizeof(*nzpres10)); - nzpres10->nzp_CSI_RS_ResourceId=10; - nzpres10->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres10->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres10->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres10->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres10->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=2; - nzpres10->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres10->resourceMapping.firstOFDMSymbolInTimeDomain=4; - nzpres10->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres10->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres10->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres10->resourceMapping.density.choice.three=(NULL_t)0; - nzpres10->resourceMapping.freqBand.startingRB=0; - nzpres10->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres10->powerControlOffset=0; - nzpres10->powerControlOffsetSS=calloc(1,sizeof(*nzpres10->powerControlOffsetSS)); - *nzpres10->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres10->scramblingID=40; - nzpres10->periodicityAndOffset = calloc(1,sizeof(*nzpres10->periodicityAndOffset)); - nzpres10->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres10->periodicityAndOffset->choice.slots160 = 25; - nzpres10->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres10->qcl_InfoPeriodicCSI_RS)); - *nzpres10->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres10); - - NR_NZP_CSI_RS_Resource_t *nzpres11 = calloc(1,sizeof(*nzpres11)); - nzpres11->nzp_CSI_RS_ResourceId=11; - nzpres11->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres11->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres11->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres11->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres11->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=2; - nzpres11->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres11->resourceMapping.firstOFDMSymbolInTimeDomain=8; - nzpres11->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres11->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres11->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres11->resourceMapping.density.choice.three=(NULL_t)0; - nzpres11->resourceMapping.freqBand.startingRB=0; - nzpres11->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres11->powerControlOffset=0; - nzpres11->powerControlOffsetSS=calloc(1,sizeof(*nzpres11->powerControlOffsetSS)); - *nzpres11->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres11->scramblingID=40; - nzpres11->periodicityAndOffset = calloc(1,sizeof(*nzpres11->periodicityAndOffset)); - nzpres11->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres11->periodicityAndOffset->choice.slots160 = 25; - nzpres11->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres11->qcl_InfoPeriodicCSI_RS)); - *nzpres11->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres11); - NR_NZP_CSI_RS_Resource_t *nzpres12 = calloc(1,sizeof(*nzpres12)); - nzpres12->nzp_CSI_RS_ResourceId=12; - nzpres12->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres12->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres12->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres12->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres12->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=2; - nzpres12->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres12->resourceMapping.firstOFDMSymbolInTimeDomain=4; - nzpres12->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres12->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres12->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres12->resourceMapping.density.choice.three=(NULL_t)0; - nzpres12->resourceMapping.freqBand.startingRB=0; - nzpres12->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres12->powerControlOffset=0; - nzpres12->powerControlOffsetSS=calloc(1,sizeof(*nzpres12->powerControlOffsetSS)); - *nzpres12->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres12->scramblingID=40; - nzpres12->periodicityAndOffset = calloc(1,sizeof(*nzpres12->periodicityAndOffset)); - nzpres12->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres12->periodicityAndOffset->choice.slots160 = 26; - nzpres12->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres12->qcl_InfoPeriodicCSI_RS)); - *nzpres12->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres12); - - NR_NZP_CSI_RS_Resource_t *nzpres13 = calloc(1,sizeof(*nzpres13)); - nzpres13->nzp_CSI_RS_ResourceId=13; - nzpres13->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres13->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres13->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres13->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres13->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=2; - nzpres13->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres13->resourceMapping.firstOFDMSymbolInTimeDomain=8; - nzpres13->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres13->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres13->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres13->resourceMapping.density.choice.three=(NULL_t)0; - nzpres13->resourceMapping.freqBand.startingRB=0; - nzpres13->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres13->powerControlOffset=0; - nzpres13->powerControlOffsetSS=calloc(1,sizeof(*nzpres13->powerControlOffsetSS)); - *nzpres13->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres13->scramblingID=40; - nzpres13->periodicityAndOffset = calloc(1,sizeof(*nzpres13->periodicityAndOffset)); - nzpres13->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres13->periodicityAndOffset->choice.slots160 = 26; - nzpres13->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres13->qcl_InfoPeriodicCSI_RS)); - *nzpres13->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres13); - NR_NZP_CSI_RS_Resource_t *nzpres14 = calloc(1,sizeof(*nzpres14)); - nzpres14->nzp_CSI_RS_ResourceId=14; - nzpres14->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres14->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres14->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres14->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres14->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=8; - nzpres14->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres14->resourceMapping.firstOFDMSymbolInTimeDomain=4; - nzpres14->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres14->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres14->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres14->resourceMapping.density.choice.three=(NULL_t)0; - nzpres14->resourceMapping.freqBand.startingRB=0; - nzpres14->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres14->powerControlOffset=0; - nzpres14->powerControlOffsetSS=calloc(1,sizeof(*nzpres14->powerControlOffsetSS)); - *nzpres14->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres14->scramblingID=40; - nzpres14->periodicityAndOffset = calloc(1,sizeof(*nzpres14->periodicityAndOffset)); - nzpres14->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres14->periodicityAndOffset->choice.slots160 = 25; - nzpres14->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres14->qcl_InfoPeriodicCSI_RS)); - *nzpres14->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres14); - - NR_NZP_CSI_RS_Resource_t *nzpres15 = calloc(1,sizeof(*nzpres15)); - nzpres15->nzp_CSI_RS_ResourceId=15; - nzpres15->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres15->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres15->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres15->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres15->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=8; - nzpres15->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres15->resourceMapping.firstOFDMSymbolInTimeDomain=8; - nzpres15->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres15->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres15->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres15->resourceMapping.density.choice.three=(NULL_t)0; - nzpres15->resourceMapping.freqBand.startingRB=0; - nzpres15->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres15->powerControlOffset=0; - nzpres15->powerControlOffsetSS=calloc(1,sizeof(*nzpres15->powerControlOffsetSS)); - *nzpres15->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres15->scramblingID=40; - nzpres15->periodicityAndOffset = calloc(1,sizeof(*nzpres15->periodicityAndOffset)); - nzpres15->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres15->periodicityAndOffset->choice.slots160 = 25; - nzpres15->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres15->qcl_InfoPeriodicCSI_RS)); - *nzpres15->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres15); - NR_NZP_CSI_RS_Resource_t *nzpres16 = calloc(1,sizeof(*nzpres16)); - nzpres16->nzp_CSI_RS_ResourceId=16; - nzpres16->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres16->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres16->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres16->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres16->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=8; - nzpres16->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres16->resourceMapping.firstOFDMSymbolInTimeDomain=5; - nzpres16->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres16->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres16->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres16->resourceMapping.density.choice.three=(NULL_t)0; - nzpres16->resourceMapping.freqBand.startingRB=0; - nzpres16->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres16->powerControlOffset=0; - nzpres16->powerControlOffsetSS=calloc(1,sizeof(*nzpres16->powerControlOffsetSS)); - *nzpres16->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres16->scramblingID=40; - nzpres16->periodicityAndOffset = calloc(1,sizeof(*nzpres16->periodicityAndOffset)); - nzpres16->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres16->periodicityAndOffset->choice.slots160 = 26; - nzpres16->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres16->qcl_InfoPeriodicCSI_RS)); - *nzpres16->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres16); - - NR_NZP_CSI_RS_Resource_t *nzpres17 = calloc(1,sizeof(*nzpres17)); - nzpres17->nzp_CSI_RS_ResourceId=9; - nzpres17->resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1; - nzpres17->resourceMapping.frequencyDomainAllocation.choice.row1.buf = calloc(1,1); - nzpres17->resourceMapping.frequencyDomainAllocation.choice.row1.size = 1; - nzpres17->resourceMapping.frequencyDomainAllocation.choice.row1.bits_unused = 4; - nzpres17->resourceMapping.frequencyDomainAllocation.choice.row1.buf[0]=8; - nzpres17->resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1; - nzpres17->resourceMapping.firstOFDMSymbolInTimeDomain=9; - nzpres17->resourceMapping.firstOFDMSymbolInTimeDomain2=NULL; - nzpres17->resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM; - nzpres17->resourceMapping.density.present=NR_CSI_RS_ResourceMapping__density_PR_three; - nzpres17->resourceMapping.density.choice.three=(NULL_t)0; - nzpres17->resourceMapping.freqBand.startingRB=0; - nzpres17->resourceMapping.freqBand.nrofRBs= servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - nzpres17->powerControlOffset=0; - nzpres17->powerControlOffsetSS=calloc(1,sizeof(*nzpres17->powerControlOffsetSS)); - *nzpres17->powerControlOffsetSS=NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0; - nzpres17->scramblingID=40; - nzpres17->periodicityAndOffset = calloc(1,sizeof(*nzpres17->periodicityAndOffset)); - nzpres17->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots160; - nzpres17->periodicityAndOffset->choice.slots160 = 26; - nzpres17->qcl_InfoPeriodicCSI_RS=calloc(1,sizeof(*nzpres17->qcl_InfoPeriodicCSI_RS)); - *nzpres17->qcl_InfoPeriodicCSI_RS=8; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpres17); - } - - if (n_physical_antenna_ports > 16) AssertFatal(1==0,"Fill in for more than 16 antenna elements\n"); - - csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList)); - csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList = NULL; - NR_NZP_CSI_RS_ResourceSet_t *nzpresset0=calloc(1,sizeof(*nzpresset0)); - nzpresset0->nzp_CSI_ResourceSetId=0; - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset00=calloc(1,sizeof(*nzpresset00)); - *nzpresset00=0; - ASN_SEQUENCE_ADD(&nzpresset0->nzp_CSI_RS_Resources.list,nzpresset00); - nzpresset0->repetition=NULL; - nzpresset0->aperiodicTriggeringOffset=NULL; - nzpresset0->trs_Info=NULL; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpresset0); - if (n_physical_antenna_ports > 1) { - NR_NZP_CSI_RS_ResourceSet_t *nzpresset3=calloc(1,sizeof(*nzpresset3)); - nzpresset3->nzp_CSI_ResourceSetId=3; - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset30=calloc(1,sizeof(*nzpresset30)); - *nzpresset30=2; - ASN_SEQUENCE_ADD(&nzpresset3->nzp_CSI_RS_Resources.list,nzpresset30); - if (n_physical_antenna_ports > 3) { - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset31=calloc(1,sizeof(*nzpresset31)); - *nzpresset31=3; - ASN_SEQUENCE_ADD(&nzpresset3->nzp_CSI_RS_Resources.list,nzpresset31); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset32=calloc(1,sizeof(*nzpresset32)); - *nzpresset32=4; - ASN_SEQUENCE_ADD(&nzpresset3->nzp_CSI_RS_Resources.list,nzpresset32); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset33=calloc(1,sizeof(*nzpresset33)); - *nzpresset33=5; - ASN_SEQUENCE_ADD(&nzpresset3->nzp_CSI_RS_Resources.list,nzpresset33); - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpresset3); - } - nzpresset3->repetition=calloc(1,sizeof(*nzpresset3->repetition)); - *nzpresset3->repetition=NR_NZP_CSI_RS_ResourceSet__repetition_off; - nzpresset3->aperiodicTriggeringOffset=NULL; - nzpresset3->trs_Info=calloc(1,sizeof(*nzpresset3->trs_Info)); - *nzpresset3->trs_Info=NR_NZP_CSI_RS_ResourceSet__trs_Info_true; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpresset3); - } - - if (n_physical_antenna_ports > 7) { - NR_NZP_CSI_RS_ResourceSet_t *nzpresset4=calloc(1,sizeof(*nzpresset4)); - nzpresset4->nzp_CSI_ResourceSetId=4; - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset40=calloc(1,sizeof(*nzpresset40)); - *nzpresset40=6; - ASN_SEQUENCE_ADD(&nzpresset4->nzp_CSI_RS_Resources.list,nzpresset40); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset41=calloc(1,sizeof(*nzpresset41)); - *nzpresset41=7; - ASN_SEQUENCE_ADD(&nzpresset4->nzp_CSI_RS_Resources.list,nzpresset41); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset42=calloc(1,sizeof(*nzpresset42)); - *nzpresset42=8; - ASN_SEQUENCE_ADD(&nzpresset4->nzp_CSI_RS_Resources.list,nzpresset42); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset43=calloc(1,sizeof(*nzpresset43)); - *nzpresset43=9; - ASN_SEQUENCE_ADD(&nzpresset4->nzp_CSI_RS_Resources.list,nzpresset43); - nzpresset4->repetition=calloc(1,sizeof(*nzpresset4->repetition)); - *nzpresset4->repetition=NR_NZP_CSI_RS_ResourceSet__repetition_off; - nzpresset4->aperiodicTriggeringOffset=NULL; - nzpresset4->trs_Info=calloc(1,sizeof(*nzpresset4->trs_Info)); - *nzpresset4->trs_Info=NR_NZP_CSI_RS_ResourceSet__trs_Info_true; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpresset4); - } - if (n_physical_antenna_ports > 15) { - NR_NZP_CSI_RS_ResourceSet_t *nzpresset5=calloc(1,sizeof(*nzpresset5)); - nzpresset5->nzp_CSI_ResourceSetId=5; - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset50=calloc(1,sizeof(*nzpresset50)); - *nzpresset50=10; - ASN_SEQUENCE_ADD(&nzpresset5->nzp_CSI_RS_Resources.list,nzpresset50); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset51=calloc(1,sizeof(*nzpresset51)); - *nzpresset51=11; - ASN_SEQUENCE_ADD(&nzpresset5->nzp_CSI_RS_Resources.list,nzpresset51); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset52=calloc(1,sizeof(*nzpresset52)); - *nzpresset52=12; - ASN_SEQUENCE_ADD(&nzpresset5->nzp_CSI_RS_Resources.list,nzpresset52); - NR_NZP_CSI_RS_ResourceSetId_t *nzpresset53=calloc(1,sizeof(*nzpresset53)); - *nzpresset53=13; - ASN_SEQUENCE_ADD(&nzpresset5->nzp_CSI_RS_Resources.list,nzpresset53); - nzpresset5->repetition=calloc(1,sizeof(*nzpresset5->repetition)); - *nzpresset5->repetition=NR_NZP_CSI_RS_ResourceSet__repetition_off; - nzpresset5->aperiodicTriggeringOffset=NULL; - nzpresset5->trs_Info=calloc(1,sizeof(*nzpresset5->trs_Info)); - *nzpresset5->trs_Info=NR_NZP_CSI_RS_ResourceSet__trs_Info_true; - ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list,nzpresset5); - } - - csi_MeasConfig->csi_IM_ResourceToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_IM_ResourceToAddModList)); + csi_MeasConfig->csi_IM_ResourceToAddModList = NULL; csi_MeasConfig->csi_IM_ResourceToReleaseList = NULL; - NR_CSI_IM_Resource_t *imres0 = calloc(1,sizeof(*imres0)); - imres0->csi_IM_ResourceId=0; - imres0->csi_IM_ResourceElementPattern=calloc(1,sizeof(*imres0->csi_IM_ResourceElementPattern)); - imres0->csi_IM_ResourceElementPattern->present = NR_CSI_IM_Resource__csi_IM_ResourceElementPattern_PR_pattern1 ; - imres0->csi_IM_ResourceElementPattern->choice.pattern1=calloc(1,sizeof(*imres0->csi_IM_ResourceElementPattern->choice.pattern1)); - imres0->csi_IM_ResourceElementPattern->choice.pattern1->subcarrierLocation_p1 = NR_CSI_IM_Resource__csi_IM_ResourceElementPattern__pattern1__subcarrierLocation_p1_s4; - imres0->csi_IM_ResourceElementPattern->choice.pattern1->symbolLocation_p1=7; - imres0->freqBand=calloc(1,sizeof(*imres0->freqBand)); - imres0->freqBand->startingRB=0; - imres0->freqBand->nrofRBs=106; - imres0->periodicityAndOffset=calloc(1,sizeof(*imres0->periodicityAndOffset)); - imres0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots320; - imres0->periodicityAndOffset->choice.slots320 = 2; - ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_IM_ResourceToAddModList->list,imres0); - csi_MeasConfig->csi_IM_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_IM_ResourceSetToAddModList)); + csi_MeasConfig->csi_IM_ResourceSetToAddModList = NULL; csi_MeasConfig->csi_IM_ResourceSetToReleaseList = NULL; - NR_CSI_IM_ResourceSet_t *imresset0 = calloc(1,sizeof(*imresset0)); - imresset0->csi_IM_ResourceSetId=0; - NR_CSI_IM_ResourceId_t *imresset00=calloc(1,sizeof(*imresset00)); - *imresset00=0; - ASN_SEQUENCE_ADD(&imresset0->csi_IM_Resources.list,imresset00); - ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_IM_ResourceSetToAddModList->list,imresset0); - + csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList = NULL; + csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList = NULL; + csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList = NULL; + csi_MeasConfig->csi_SSB_ResourceSetToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_SSB_ResourceSetToAddModList)); csi_MeasConfig->csi_SSB_ResourceSetToReleaseList = NULL; + NR_CSI_SSB_ResourceSet_t *ssbresset0 = calloc(1,sizeof(*ssbresset0)); - ssbresset0->csi_SSB_ResourceSetId=0; - NR_SSB_Index_t *ssbresset00=calloc(1,sizeof(*ssbresset00)); - *ssbresset00=0; - ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset00); - if (n_physical_antenna_ports > 1) { + ssbresset0->csi_SSB_ResourceSetId=0; + if ((bitmap>>7)&0x01){ + NR_SSB_Index_t *ssbresset00=calloc(1,sizeof(*ssbresset00)); + *ssbresset00=0; + ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset00); + } + if ((bitmap>>6)&0x01) { NR_SSB_Index_t *ssbresset01=calloc(1,sizeof(*ssbresset01)); *ssbresset01=1; ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset01); } - if (n_physical_antenna_ports > 3) { + if ((bitmap>>5)&0x01) { NR_SSB_Index_t *ssbresset02=calloc(1,sizeof(*ssbresset02)); *ssbresset02=2; ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset02); + } + if ((bitmap>>4)&0x01) { NR_SSB_Index_t *ssbresset03=calloc(1,sizeof(*ssbresset03)); *ssbresset03=3; ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset03); } - if (n_physical_antenna_ports > 7) { + if ((bitmap>>3)&0x01) { NR_SSB_Index_t *ssbresset04=calloc(1,sizeof(*ssbresset04)); *ssbresset04=4; ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset04); + } + if ((bitmap>>2)&0x01) { NR_SSB_Index_t *ssbresset05=calloc(1,sizeof(*ssbresset05)); *ssbresset05=5; ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset05); + } + if ((bitmap>>1)&0x01) { NR_SSB_Index_t *ssbresset06=calloc(1,sizeof(*ssbresset06)); *ssbresset06=6; ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset06); + } + if ((bitmap)&0x01) { NR_SSB_Index_t *ssbresset07=calloc(1,sizeof(*ssbresset07)); *ssbresset07=7; ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset07); @@ -1779,222 +1124,21 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco csires0->csi_ResourceConfigId=0; csires0->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); - csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); - csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = NULL; - NR_NZP_CSI_RS_ResourceSetId_t *csires00 = calloc(1,sizeof(*csires00)); - *csires00 = 0; - ASN_SEQUENCE_ADD(&csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,csires00); + csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = NULL; + csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = calloc(1,sizeof(*csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList)); + NR_CSI_SSB_ResourceSetId_t *ssbres00 = calloc(1,sizeof(*ssbres00)); + *ssbres00 = 0; + ASN_SEQUENCE_ADD(&csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list,ssbres00); csires0->bwp_Id = 1; csires0->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires0); - NR_CSI_ResourceConfig_t *csires11 = calloc(1,sizeof(*csires11)); - csires11->csi_ResourceConfigId=11; - csires11->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_csi_IM_ResourceSetList; - csires11->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList = calloc(1,sizeof(*csires11->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList)); - NR_NZP_CSI_RS_ResourceSetId_t *csires110 = calloc(1,sizeof(*csires110)); - *csires110 = 0; - ASN_SEQUENCE_ADD(&csires11->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList->list,csires110); - csires11->bwp_Id = 1; - csires11->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; - //ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires11); - - NR_CSI_ResourceConfig_t *csires10 = calloc(1,sizeof(*csires10)); - csires10->csi_ResourceConfigId=10; - csires10->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; - csires10->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires10->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); - csires10->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires10->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); - csires10->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = NULL; - NR_NZP_CSI_RS_ResourceSetId_t *csires100 = calloc(1,sizeof(*csires100)); - *csires100 = 0; - ASN_SEQUENCE_ADD(&csires10->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,csires100); - csires10->bwp_Id = 1; - csires10->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; - //ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires10); - - NR_CSI_ResourceConfig_t *csires2 = calloc(1,sizeof(*csires2)); - csires2->csi_ResourceConfigId=2; - csires2->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; - csires2->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires2->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); - csires2->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires2->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); - csires2->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = NULL; - NR_NZP_CSI_RS_ResourceSetId_t *csires20 = calloc(1,sizeof(*csires20)); - *csires20 = 0; - ASN_SEQUENCE_ADD(&csires2->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,csires20); - csires2->bwp_Id = 1; - csires2->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; - //ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires2); - - NR_CSI_ResourceConfig_t *csires3 = calloc(1,sizeof(*csires3)); - csires3->csi_ResourceConfigId=3; - csires3->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; - csires3->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires3->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); - csires3->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires3->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); - csires3->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = NULL; - NR_NZP_CSI_RS_ResourceSetId_t *csires30 = calloc(1,sizeof(*csires30)); - *csires30 = 0; - ASN_SEQUENCE_ADD(&csires3->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,csires30); - csires3->bwp_Id = 1; - csires3->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; - //ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires3); - - NR_CSI_ResourceConfig_t *csires4 = calloc(1,sizeof(*csires4)); - csires4->csi_ResourceConfigId=4; - csires4->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; - csires4->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires4->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); - csires4->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires4->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); - csires4->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = NULL; - NR_NZP_CSI_RS_ResourceSetId_t *csires40 = calloc(1,sizeof(*csires40)); - *csires40 = 0; - ASN_SEQUENCE_ADD(&csires4->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,csires40); - csires4->bwp_Id = 1; - csires4->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; - //ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires4); - - NR_CSI_ResourceConfig_t *csires5 = calloc(1,sizeof(*csires5)); - csires5->csi_ResourceConfigId=5; - csires5->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; - csires5->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires5->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); - csires5->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires5->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); - csires5->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = NULL; - NR_NZP_CSI_RS_ResourceSetId_t *csires50 = calloc(1,sizeof(*csires50)); - *csires50 = 0; - ASN_SEQUENCE_ADD(&csires5->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,csires50); - csires5->bwp_Id = 1; - csires5->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; - //ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires5); - - NR_CSI_ResourceConfig_t *csires6 = calloc(1,sizeof(*csires6)); - csires6->csi_ResourceConfigId=6; - csires6->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; - csires6->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires6->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); - csires6->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires6->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); - csires6->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = NULL; - NR_NZP_CSI_RS_ResourceSetId_t *csires60 = calloc(1,sizeof(*csires60)); - *csires60 = 0; - ASN_SEQUENCE_ADD(&csires6->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,csires60); - csires6->bwp_Id = 1; - csires6->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; - //ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires6); - - NR_CSI_ResourceConfig_t *csires7 = calloc(1,sizeof(*csires7)); - csires7->csi_ResourceConfigId=7; - csires7->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; - csires7->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires7->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); - csires7->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires7->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); - csires7->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = NULL; - NR_NZP_CSI_RS_ResourceSetId_t *csires70 = calloc(1,sizeof(*csires70)); - *csires70 = 0; - ASN_SEQUENCE_ADD(&csires7->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,csires70); - csires7->bwp_Id = 1; - csires7->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; - //ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires7); - - NR_CSI_ResourceConfig_t *csires8 = calloc(1,sizeof(*csires8)); - csires8->csi_ResourceConfigId=8; - csires8->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; - csires8->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires8->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); - csires8->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires8->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); - csires8->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = NULL; - NR_NZP_CSI_RS_ResourceSetId_t *csires80 = calloc(1,sizeof(*csires80)); - *csires80 = 0; - ASN_SEQUENCE_ADD(&csires8->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,csires80); - csires8->bwp_Id = 1; - csires8->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; - //ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires8); - - NR_CSI_ResourceConfig_t *csires9 = calloc(1,sizeof(*csires9)); - csires9->csi_ResourceConfigId=9; - csires9->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; - csires9->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires9->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); - csires9->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1,sizeof(*csires9->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); - csires9->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = NULL; - NR_NZP_CSI_RS_ResourceSetId_t *csires90 = calloc(1,sizeof(*csires90)); - *csires90 = 0; - ASN_SEQUENCE_ADD(&csires9->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list,csires90); - csires9->bwp_Id = 1; - csires9->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; - //ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires9); - csi_MeasConfig->csi_ReportConfigToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_ReportConfigToAddModList)); csi_MeasConfig->csi_ReportConfigToReleaseList = NULL; - NR_CSI_ReportConfig_t *csirep0 = calloc(1,sizeof(*csirep0)); - csirep0->reportConfigId=0; - csirep0->carrier=NULL; - csirep0->resourcesForChannelMeasurement=0; - csirep0->csi_IM_ResourcesForInterference=calloc(1,sizeof(*csirep0->csi_IM_ResourcesForInterference)); - *csirep0->csi_IM_ResourcesForInterference=11; - csirep0->nzp_CSI_RS_ResourcesForInterference=NULL; - csirep0->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic; - csirep0->reportConfigType.choice.periodic = calloc(1,sizeof(*csirep0->reportConfigType.choice.periodic)); - csirep0->reportConfigType.choice.periodic->reportSlotConfig.present=NR_CSI_ReportPeriodicityAndOffset_PR_slots320; - csirep0->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 9; - - NR_PUCCH_CSI_Resource_t *pucchcsires0 = calloc(1,sizeof(*pucchcsires0)); - pucchcsires0->uplinkBandwidthPartId=1; - pucchcsires0->pucch_Resource=11; - ASN_SEQUENCE_ADD(&csirep0->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list,pucchcsires0); - csirep0->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI; - csirep0->reportQuantity.choice.cri_RI_PMI_CQI = (NULL_t)0; - csirep0->reportFreqConfiguration = calloc(1,sizeof(*csirep0->reportFreqConfiguration)); - csirep0->reportFreqConfiguration->cqi_FormatIndicator=NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI; - csirep0->reportFreqConfiguration->pmi_FormatIndicator=NR_CSI_ReportConfig__reportFreqConfiguration__pmi_FormatIndicator_widebandPMI; - csirep0->reportFreqConfiguration->csi_ReportingBand=calloc(1,sizeof(*csirep0->reportFreqConfiguration->csi_ReportingBand)); - - - AssertFatal(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id>0,"firstActiveDownlinkBWP_Id %d\n",(int)*secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id); - int NPRB = NRRIV2BW(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[*secondaryCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id-1]->bwp_Common->genericParameters.locationAndBandwidth,275); - int sbsize = get_subband_size(NPRB,0); - int numsb = NPRB/sbsize; - if (NPRB%sbsize == 0) numsb++; - csirep0->reportFreqConfiguration->csi_ReportingBand->present= NR_CSI_ReportConfig__reportFreqConfiguration__csi_ReportingBand_PR_NOTHING+(numsb-2); - csirep0->reportFreqConfiguration->csi_ReportingBand->choice.subbands18.size=numsb/8; - if ((numsb&7) > 0) csirep0->reportFreqConfiguration->csi_ReportingBand->choice.subbands18.size++; - csirep0->reportFreqConfiguration->csi_ReportingBand->choice.subbands18.bits_unused = (8-(numsb&7))&7; - csirep0->reportFreqConfiguration->csi_ReportingBand->choice.subbands18.buf=malloc(csirep0->reportFreqConfiguration->csi_ReportingBand->choice.subbands18.size); - for (int i=0;ireportFreqConfiguration->csi_ReportingBand->choice.subbands18.size;i++) - csirep0->reportFreqConfiguration->csi_ReportingBand->choice.subbands18.buf[i]=0xff; - csirep0->reportFreqConfiguration->csi_ReportingBand->choice.subbands18.buf[csirep0->reportFreqConfiguration->csi_ReportingBand->choice.subbands18.size-1]&=~((1<reportFreqConfiguration->csi_ReportingBand->choice.subbands18.bits_unused)-1); - - csirep0->timeRestrictionForChannelMeasurements= NR_CSI_ReportConfig__timeRestrictionForChannelMeasurements_configured; - csirep0->timeRestrictionForInterferenceMeasurements=NR_CSI_ReportConfig__timeRestrictionForInterferenceMeasurements_configured; - csirep0->codebookConfig=calloc(1,sizeof(*csirep0->codebookConfig)); - csirep0->codebookConfig->codebookType.present = NR_CodebookConfig__codebookType_PR_type1; - csirep0->codebookConfig->codebookType.choice.type1 = calloc(1,sizeof(*csirep0->codebookConfig->codebookType.choice.type1)); - csirep0->codebookConfig->codebookType.choice.type1->subType.present = NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel; - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel=calloc(1,sizeof(*csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel)); - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present=NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two; - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two= - calloc(1,sizeof(*csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two)); - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.size=1; - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.bits_unused=2; - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf=malloc(1); - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.two->twoTX_CodebookSubsetRestriction.buf[0]=0xfc; - //'111111'B - - - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.size=1; - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.bits_unused=0; - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf=malloc(1); - csirep0->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]=0xc0; //'00000011'B - - csirep0->codebookConfig->codebookType.choice.type1->codebookMode=1; - csirep0->dummy = NULL; - csirep0->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled; - csirep0->groupBasedBeamReporting.choice.disabled=calloc(1,sizeof(*csirep0->groupBasedBeamReporting.choice.disabled)); - csirep0->groupBasedBeamReporting.choice.disabled->nrofReportedRS = NULL; - csirep0->cqi_Table = calloc(1,sizeof(*csirep0->cqi_Table)); - *csirep0->cqi_Table = NR_CSI_ReportConfig__cqi_Table_table1; - csirep0->subbandSize = NR_CSI_ReportConfig__subbandSize_value1; - csirep0->non_PMI_PortIndication = NULL; - csirep0->ext1 = NULL; - - ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ReportConfigToAddModList->list,csirep0); - NR_CSI_ReportConfig_t *csirep1 = calloc(1,sizeof(*csirep1)); - csirep1->reportConfigId=2; + csirep1->reportConfigId=0; csirep1->carrier=NULL; - csirep1->resourcesForChannelMeasurement=initial_csi_index; + csirep1->resourcesForChannelMeasurement=0; csirep1->csi_IM_ResourcesForInterference=NULL; csirep1->nzp_CSI_RS_ResourcesForInterference=NULL; csirep1->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic; @@ -2003,7 +1147,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco csirep1->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320 = 49; NR_PUCCH_CSI_Resource_t *pucchcsires1 = calloc(1,sizeof(*pucchcsires1)); pucchcsires1->uplinkBandwidthPartId=1; - pucchcsires1->pucch_Resource=12; + pucchcsires1->pucch_Resource=3; ASN_SEQUENCE_ADD(&csirep1->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list,pucchcsires1); csirep1->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP; csirep1->reportQuantity.choice.ssb_Index_RSRP=(NULL_t)0; @@ -2038,7 +1182,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco csirep1->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled; csirep1->groupBasedBeamReporting.choice.disabled=calloc(1,sizeof(*csirep1->groupBasedBeamReporting.choice.disabled)); csirep1->groupBasedBeamReporting.choice.disabled->nrofReportedRS = calloc(1,sizeof(*csirep1->groupBasedBeamReporting.choice.disabled->nrofReportedRS)); - *csirep1->groupBasedBeamReporting.choice.disabled->nrofReportedRS=NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n2; + *csirep1->groupBasedBeamReporting.choice.disabled->nrofReportedRS=NR_CSI_ReportConfig__groupBasedBeamReporting__disabled__nrofReportedRS_n1; // this corresponds to: //if the UE is configured with the higher layer parameter groupBasedBeamReporting set to 'disabled', the UE is not required to update measurements for more than 64 CSI-RS and/or SSB resources, and the UE shall report in a single report nrofReportedRS (higher layer configured) different CRI or SSBRI for each report setting. @@ -2050,7 +1194,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ReportConfigToAddModList->list,csirep1); - secondaryCellGroup->spCellConfig->spCellConfigDedicated->sCellDeactivationTimer=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->tag_Id=0; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index fb1dc82986..4fcd0db1b5 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -192,6 +192,7 @@ extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * con // from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded) int8_t nr_rrc_ue_decode_secondary_cellgroup_config( + const module_id_t module_id, const uint8_t *buffer, const uint32_t size ){ @@ -215,11 +216,11 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config( return -1; } - if(NR_UE_rrc_inst->cell_group_config == NULL){ - NR_UE_rrc_inst->cell_group_config = cell_group_config; - nr_rrc_ue_process_scg_config(cell_group_config); + if(NR_UE_rrc_inst[module_id].cell_group_config == NULL){ + NR_UE_rrc_inst[module_id].cell_group_config = cell_group_config; + nr_rrc_ue_process_scg_config(module_id,cell_group_config); }else{ - nr_rrc_ue_process_scg_config(cell_group_config); + nr_rrc_ue_process_scg_config(module_id,cell_group_config); SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 0); } @@ -239,67 +240,62 @@ int8_t nr_rrc_ue_process_RadioBearerConfig(NR_RadioBearerConfig_t *RadioBearerCo // from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (decoded) // RRCReconfiguration -int8_t nr_rrc_ue_process_rrcReconfiguration(NR_RRCReconfiguration_t *rrcReconfiguration){ +int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration){ - switch(rrcReconfiguration->criticalExtensions.present){ - case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig != NULL){ - if(NR_UE_rrc_inst->radio_bearer_config == NULL){ - NR_UE_rrc_inst->radio_bearer_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig; - }else{ - nr_rrc_ue_process_RadioBearerConfig(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig); - } - } + switch(rrcReconfiguration->criticalExtensions.present){ + case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: + if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig != NULL){ + if(NR_UE_rrc_inst[module_id].radio_bearer_config == NULL){ + NR_UE_rrc_inst[module_id].radio_bearer_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig; + }else{ + nr_rrc_ue_process_RadioBearerConfig(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig); + } + } + if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){ + NR_CellGroupConfig_t *cellGroupConfig = NULL; + uper_decode(NULL, + &asn_DEF_NR_CellGroupConfig, //might be added prefix later + (void **)&cellGroupConfig, + (uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf, + rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size, 0, 0); - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){ - NR_CellGroupConfig_t *cellGroupConfig = NULL; - uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, //might be added prefix later - (void **)&cellGroupConfig, - (uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf, - rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size, 0, 0); + xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)cellGroupConfig); - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)cellGroupConfig); + if(NR_UE_rrc_inst[module_id].cell_group_config == NULL){ + // first time receive the configuration, just use the memory allocated from uper_decoder. TODO this is not good implementation, need to maintain RRC_INST own structure every time. + NR_UE_rrc_inst[module_id].cell_group_config = cellGroupConfig; + nr_rrc_ue_process_scg_config(module_id,cellGroupConfig); + }else{ + // after first time, update it and free the memory after. + SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)NR_UE_rrc_inst[module_id].cell_group_config, 0); + NR_UE_rrc_inst[module_id].cell_group_config = cellGroupConfig; + nr_rrc_ue_process_scg_config(module_id,cellGroupConfig); + } + } + if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig != NULL){ + if(NR_UE_rrc_inst[module_id].meas_config == NULL){ + NR_UE_rrc_inst[module_id].meas_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig; + }else{ + // if some element need to be updated + nr_rrc_ue_process_meas_config(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig); + } + } + if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->lateNonCriticalExtension != NULL){ + // unuse now + } + if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->nonCriticalExtension != NULL){ + // unuse now + } + break; + + case NR_RRCReconfiguration__criticalExtensions_PR_NOTHING: + case NR_RRCReconfiguration__criticalExtensions_PR_criticalExtensionsFuture: + default: + break; + } + //nr_rrc_mac_config_req_ue(); - if(NR_UE_rrc_inst->cell_group_config == NULL){ - // first time receive the configuration, just use the memory allocated from uper_decoder. TODO this is not good implementation, need to maintain RRC_INST own structure every time. - NR_UE_rrc_inst->cell_group_config = cellGroupConfig; - nr_rrc_ue_process_scg_config(cellGroupConfig); - }else{ - // after first time, update it and free the memory after. - SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)NR_UE_rrc_inst->cell_group_config, 0); - NR_UE_rrc_inst->cell_group_config = cellGroupConfig; - nr_rrc_ue_process_scg_config(cellGroupConfig); - } - - } - - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig != NULL){ - if(NR_UE_rrc_inst->meas_config == NULL){ - NR_UE_rrc_inst->meas_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig; - }else{ - // if some element need to be updated - nr_rrc_ue_process_meas_config(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig); - } - - } - - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->lateNonCriticalExtension != NULL){ - // unuse now - } - - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->nonCriticalExtension != NULL){ - // unuse now - } - break; - case NR_RRCReconfiguration__criticalExtensions_PR_NOTHING: - case NR_RRCReconfiguration__criticalExtensions_PR_criticalExtensionsFuture: - default: - break; - } - //nr_rrc_mac_config_req_ue(); - - return 0; + return 0; } @@ -309,90 +305,89 @@ int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config){ return 0; } -int8_t nr_rrc_ue_process_scg_config(NR_CellGroupConfig_t *cell_group_config){ - int i; - if(NR_UE_rrc_inst->cell_group_config==NULL){ - // initial list - if(cell_group_config->spCellConfig != NULL){ - if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ - if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ - for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; ++i){ - RRC_LIST_MOD_ADD(NR_UE_rrc_inst->BWP_Downlink_list, cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i], bwp_Id); - } - } - } - } - }else{ - // maintain list - if(cell_group_config->spCellConfig != NULL){ - if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ - // process element of list to be add by RRC message - if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ - for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; ++i){ - RRC_LIST_MOD_ADD(NR_UE_rrc_inst->BWP_Downlink_list, cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i], bwp_Id); - } - } - - - // process element of list to be release by RRC message - if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList != NULL){ - for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList->list.count; ++i){ - NR_BWP_Downlink_t *freeP = NULL; - RRC_LIST_MOD_REL(NR_UE_rrc_inst->BWP_Downlink_list, bwp_Id, *cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList->list.array[i], freeP); - if(freeP != NULL){ - SEQUENCE_free(&asn_DEF_NR_BWP_Downlink, (void *)freeP, 0); - } - } - } - } +int8_t nr_rrc_ue_process_scg_config(const module_id_t module_id, NR_CellGroupConfig_t *cell_group_config){ + int i; + if(NR_UE_rrc_inst[module_id].cell_group_config==NULL){ + // initial list + if(cell_group_config->spCellConfig != NULL){ + if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ + if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ + for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; ++i){ + RRC_LIST_MOD_ADD(NR_UE_rrc_inst[module_id].BWP_Downlink_list, cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i], bwp_Id); + } + } + } + } + }else{ + // maintain list + if(cell_group_config->spCellConfig != NULL){ + if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ + // process element of list to be add by RRC message + if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ + for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; ++i){ + RRC_LIST_MOD_ADD(NR_UE_rrc_inst[module_id].BWP_Downlink_list, cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i], bwp_Id); + } } - } - return 0; + // process element of list to be release by RRC message + if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList != NULL){ + for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList->list.count; ++i){ + NR_BWP_Downlink_t *freeP = NULL; + RRC_LIST_MOD_REL(NR_UE_rrc_inst[module_id].BWP_Downlink_list, bwp_Id, *cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList->list.array[i], freeP); + if(freeP != NULL){ + SEQUENCE_free(&asn_DEF_NR_BWP_Downlink, (void *)freeP, 0); + } + } + } + } + } + } + + return 0; } - - void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message,int msg_len) { - + module_id_t module_id=0; // TODO switch (nsa_message_type) { case nr_SecondaryCellGroupConfig_r15: { - NR_RRCReconfiguration_t *RRCReconfiguration=NULL; - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_RRCReconfiguration, - (void **)&RRCReconfiguration, - (uint8_t *)message, - msg_len); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(RRC,"NR_RRCReconfiguration decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 ); - return; - } - nr_rrc_ue_process_rrcReconfiguration(RRCReconfiguration); - } + NR_RRCReconfiguration_t *RRCReconfiguration=NULL; + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_RRCReconfiguration, + (void **)&RRCReconfiguration, + (uint8_t *)message, + msg_len); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC,"NR_RRCReconfiguration decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 ); + return; + } + nr_rrc_ue_process_rrcReconfiguration(module_id,RRCReconfiguration); + } break; + case nr_RadioBearerConfigX_r15: { - NR_RadioBearerConfig_t *RadioBearerConfig=NULL; - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_RadioBearerConfig, - (void **)&RadioBearerConfig, - (uint8_t *)message, - msg_len); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(RRC,"NR_RadioBearerConfig decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 ); - return; - } - nr_rrc_ue_process_RadioBearerConfig(RadioBearerConfig); + NR_RadioBearerConfig_t *RadioBearerConfig=NULL; + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_RadioBearerConfig, + (void **)&RadioBearerConfig, + (uint8_t *)message, + msg_len); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC,"NR_RadioBearerConfig decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 ); + return; + } + nr_rrc_ue_process_RadioBearerConfig(RadioBearerConfig); } break; + default: AssertFatal(1==0,"Unknown message %d\n",nsa_message_type); break; @@ -401,104 +396,105 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, } NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ - - if(NB_NR_UE_INST > 0){ - NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)malloc(NB_NR_UE_INST * sizeof(NR_UE_RRC_INST_t)); - memset(NR_UE_rrc_inst, 0, NB_NR_UE_INST * sizeof(NR_UE_RRC_INST_t)); - - // fill UE-NR-Capability @ UE-CapabilityRAT-Container here. - NR_UE_rrc_inst[0].selected_plmn_identity = 1; - // init RRC lists - RRC_LIST_INIT(NR_UE_rrc_inst->RLC_Bearer_Config_list, NR_maxLC_ID); - RRC_LIST_INIT(NR_UE_rrc_inst->SchedulingRequest_list, NR_maxNrofSR_ConfigPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->TAG_list, NR_maxNrofTAGs); - RRC_LIST_INIT(NR_UE_rrc_inst->TDD_UL_DL_SlotConfig_list, NR_maxNrofSlots); - RRC_LIST_INIT(NR_UE_rrc_inst->BWP_Downlink_list, NR_maxNrofBWPs); - RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[0], 3); // for init-dl-bwp - RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[1], 3); // for dl-bwp id=0 - RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[2], 3); // for dl-bwp id=1 - RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[3], 3); // for dl-bwp id=2 - RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[4], 3); // for dl-bwp id=3 - RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list[0], 10); - RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list[1], 10); - RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list[2], 10); - RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list[3], 10); - RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list[4], 10); - RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list[0], NR_maxNrofAggregatedCellsPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list[1], NR_maxNrofAggregatedCellsPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list[2], NR_maxNrofAggregatedCellsPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list[3], NR_maxNrofAggregatedCellsPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list[4], NR_maxNrofAggregatedCellsPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list[0], NR_maxNrofTCI_States); - RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list[1], NR_maxNrofTCI_States); - RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list[2], NR_maxNrofTCI_States); - RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list[3], NR_maxNrofTCI_States); - RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list[4], NR_maxNrofTCI_States); - RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list[0], NR_maxNrofRateMatchPatterns); - RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list[1], NR_maxNrofRateMatchPatterns); - RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list[2], NR_maxNrofRateMatchPatterns); - RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list[3], NR_maxNrofRateMatchPatterns); - RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list[4], NR_maxNrofRateMatchPatterns); - RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list[0], NR_maxNrofZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list[1], NR_maxNrofZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list[2], NR_maxNrofZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list[3], NR_maxNrofZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list[4], NR_maxNrofZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list[0], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list[1], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list[2], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list[3], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list[4], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list[0], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list[1], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list[2], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list[3], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list[4], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->NZP_CSI_RS_Resource_list, NR_maxNrofNZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->NZP_CSI_RS_ResourceSet_list, NR_maxNrofNZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->CSI_IM_Resource_list, NR_maxNrofCSI_IM_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->CSI_IM_ResourceSet_list, NR_maxNrofCSI_IM_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->CSI_SSB_ResourceSet_list, NR_maxNrofCSI_SSB_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ResourceConfig_list, NR_maxNrofCSI_ResourceConfigurations); - RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations); - - if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) { - // read in files for RRCReconfiguration and RBconfig - FILE *fd; - char filename[1024]; - if (rrc_config_path) - sprintf(filename,"%s/reconfig.raw",rrc_config_path); - else - sprintf(filename,"reconfig.raw"); - fd = fopen(filename,"r"); - char buffer[1024]; - AssertFatal(fd, - "cannot read file %s: errno %d, %s\n", - filename, - errno, - strerror(errno)); - int msg_len=fread(buffer,1,1024,fd); - fclose(fd); - process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); - if (rrc_config_path) - sprintf(filename,"%s/rbconfig.raw",rrc_config_path); - else - sprintf(filename,"rbconfig.raw"); - fd = fopen(filename,"r"); - AssertFatal(fd, - "cannot read file %s: errno %d, %s\n", - filename, - errno, - strerror(errno)); - msg_len=fread(buffer,1,1024,fd); - fclose(fd); - process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); - } - }else{ - NR_UE_rrc_inst = NULL; + int nr_ue; + if(NB_NR_UE_INST > 0){ + NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)malloc(NB_NR_UE_INST * sizeof(NR_UE_RRC_INST_t)); + memset(NR_UE_rrc_inst, 0, NB_NR_UE_INST * sizeof(NR_UE_RRC_INST_t)); + for(nr_ue=0;nr_uephy_test==1 || get_softmodem_params()->do_ra==1) { + // read in files for RRCReconfiguration and RBconfig + FILE *fd; + char filename[1024]; + if (rrc_config_path) + sprintf(filename,"%s/reconfig.raw",rrc_config_path); + else + sprintf(filename,"reconfig.raw"); + fd = fopen(filename,"r"); + char buffer[1024]; + AssertFatal(fd, + "cannot read file %s: errno %d, %s\n", + filename, + errno, + strerror(errno)); + int msg_len=fread(buffer,1,1024,fd); + fclose(fd); + process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); + if (rrc_config_path) + sprintf(filename,"%s/rbconfig.raw",rrc_config_path); + else + sprintf(filename,"rbconfig.raw"); + fd = fopen(filename,"r"); + AssertFatal(fd, + "cannot read file %s: errno %d, %s\n", + filename, + errno, + strerror(errno)); + msg_len=fread(buffer,1,1024,fd); + fclose(fd); + process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); + } + }else{ + NR_UE_rrc_inst = NULL; + } + + return NR_UE_rrc_inst; } @@ -535,7 +531,7 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message( const uint8_t buffer_len ){ int i; NR_BCCH_BCH_Message_t *bcch_message = NULL; - NR_MIB_t *mib = NR_UE_rrc_inst->mib; + NR_MIB_t *mib = NR_UE_rrc_inst[module_id].mib; if(mib != NULL){ SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)mib, 1 ); @@ -555,7 +551,7 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message( if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { printf("NR_BCCH_BCH decode error\n"); for (i=0; ispCellConfig != NULL && cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL){ - //TODO (perform Reconfiguration with sync according to 5.3.5.5.2) - //TODO (resume all suspended radio bearers and resume SCG transmission for all radio bearers, if suspended) - } + NR_CellGroupConfig_t *cellGroupConfig = (NR_CellGroupConfig_t *)masterCellGroup; + if( cellGroupConfig->spCellConfig != NULL && cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL){ + //TODO (perform Reconfiguration with sync according to 5.3.5.5.2) + //TODO (resume all suspended radio bearers and resume SCG transmission for all radio bearers, if suspended) + } - if( cellGroupConfig->rlc_BearerToReleaseList != NULL){ - //TODO (perform RLC bearer release as specified in 5.3.5.5.3) - } + if( cellGroupConfig->rlc_BearerToReleaseList != NULL){ + //TODO (perform RLC bearer release as specified in 5.3.5.5.3) + } - if( cellGroupConfig->rlc_BearerToAddModList != NULL){ - //TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4) - } + if( cellGroupConfig->rlc_BearerToAddModList != NULL){ + //TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4) + } - if( cellGroupConfig->mac_CellGroupConfig != NULL){ - //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5) - } + if( cellGroupConfig->mac_CellGroupConfig != NULL){ + //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5) + } - if( cellGroupConfig->sCellToReleaseList != NULL){ - //TODO (perform SCell release as specified in 5.3.5.5.8) - } + if( cellGroupConfig->sCellToReleaseList != NULL){ + //TODO (perform SCell release as specified in 5.3.5.5.8) + } - if( cellGroupConfig->spCellConfig != NULL){ - if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig) { - memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig,cellGroupConfig->spCellConfig, - sizeof(struct NR_SpCellConfig)); - } else { - NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig = cellGroupConfig->spCellConfig; - } - //TODO (configure the SpCell as specified in 5.3.5.5.7) + if( cellGroupConfig->spCellConfig != NULL){ + if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig) { + memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig,cellGroupConfig->spCellConfig, + sizeof(struct NR_SpCellConfig)); + } else { + NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig = cellGroupConfig->spCellConfig; } + //TODO (configure the SpCell as specified in 5.3.5.5.7) + } - if( cellGroupConfig->sCellToAddModList != NULL){ - //TODO (perform SCell addition/modification as specified in 5.3.5.5.9) - } + if( cellGroupConfig->sCellToAddModList != NULL){ + //TODO (perform SCell addition/modification as specified in 5.3.5.5.9) + } - if( cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){ - //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11) - } - - if( cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){ - //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11) - } + if( cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){ + //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11) + } + if( cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){ + //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11) + } } /*--------------------------------------------------*/ static void rrc_ue_generate_RRCSetupComplete( - const protocol_ctxt_t *const ctxt_pP, - const uint8_t gNB_index, - const uint8_t Transaction_id, - uint8_t sel_plmn_id){ - uint8_t buffer[100]; - uint8_t size; - const char *nas_msg; - int nas_msg_length; - if (AMF_MODE_ENABLED) { + const protocol_ctxt_t *const ctxt_pP, + const uint8_t gNB_index, + const uint8_t Transaction_id, + uint8_t sel_plmn_id){ + + uint8_t buffer[100]; + uint8_t size; + const char *nas_msg; + int nas_msg_length; + if (AMF_MODE_ENABLED) { #if ITTI_SIM - as_nas_info_t initialNasMsg; - generateRegistrationRequest(&initialNasMsg); - nas_msg = (char*)initialNasMsg.data; - nas_msg_length = initialNasMsg.length; + as_nas_info_t initialNasMsg; + generateRegistrationRequest(&initialNasMsg); + nas_msg = (char*)initialNasMsg.data; + nas_msg_length = initialNasMsg.length; #else - nas_msg = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data; - nas_msg_length = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length; + nas_msg = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data; + nas_msg_length = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length; #endif - } else { - nas_msg = nr_nas_attach_req_imsi; - nas_msg_length = sizeof(nr_nas_attach_req_imsi); - } - size = do_RRCSetupComplete(ctxt_pP->module_id,buffer,Transaction_id,sel_plmn_id,nas_msg_length,nas_msg); - LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n", - ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index); - LOG_D(RLC, - "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", - ctxt_pP->frame, ctxt_pP->module_id+NB_RN_INST, size, gNB_index, nr_rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH); - // ctxt_pP_local.rnti = ctxt_pP->rnti; - rrc_data_req_ue( - ctxt_pP, - DCCH, - nr_rrc_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + } else { + nas_msg = nr_nas_attach_req_imsi; + nas_msg_length = sizeof(nr_nas_attach_req_imsi); + } + size = do_RRCSetupComplete(ctxt_pP->module_id,buffer,Transaction_id,sel_plmn_id,nas_msg_length,nas_msg); + LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n", + ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index); + LOG_D(RLC, + "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", + ctxt_pP->frame, ctxt_pP->module_id+NB_RN_INST, size, gNB_index, nr_rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH); + // ctxt_pP_local.rnti = ctxt_pP->rnti; + rrc_data_req_ue( + ctxt_pP, + DCCH, + nr_rrc_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_UE_SIM, TASK_RRC_GNB_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, UE_RRC_DCCH_DATA_IND); - UE_RRC_DCCH_DATA_IND (message_p).rbid = 1; - UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - UE_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_UE_SIM, TASK_RRC_GNB_SIM, size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, UE_RRC_DCCH_DATA_IND); + UE_RRC_DCCH_DATA_IND (message_p).rbid = 1; + UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + UE_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); #endif } int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ){ - NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; - asn_dec_rval_t dec_rval; - int rval=0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN); - // LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size, - // NR_UE_rrc_inst[ue_mod_idP].Info[gNB_index].State); - dec_rval = uper_decode(NULL, - &asn_DEF_NR_DL_CCCH_Message, - (void **)&dl_ccch_msg, - (uint8_t *)Srb_info->Rx_buffer.Payload, - 100,0,0); - - // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg); - // } - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) { - LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); - return -1; - } - - if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) { - if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_SI_RECEIVED) { - switch (dl_ccch_msg->message.choice.c1->present) { - case NR_DL_CCCH_MessageType__c1_PR_NOTHING: - LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n", - ctxt_pP->module_id, - ctxt_pP->frame); - rval = 0; - break; - - case NR_DL_CCCH_MessageType__c1_PR_rrcReject: - LOG_I(NR_RRC, - "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n", - ctxt_pP->module_id, - ctxt_pP->frame); - rval = 0; - break; - - case NR_DL_CCCH_MessageType__c1_PR_rrcSetup: - LOG_I(NR_RRC, - "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n", - ctxt_pP->module_id, - ctxt_pP->frame, - ctxt_pP->rnti); - // Get configuration - // Release T300 timer - NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0; - - nr_rrc_ue_process_masterCellGroup( - ctxt_pP, - gNB_index, - &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup); - nr_sa_rrc_ue_process_radioBearerConfig( - ctxt_pP, - gNB_index, - &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); - nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED); - nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED); - NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti; - rrc_ue_generate_RRCSetupComplete( - ctxt_pP, - gNB_index, - dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier, - NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); - rval = 0; - break; - - default: - LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n", - ctxt_pP->module_id, - ctxt_pP->frame); - rval = -1; - break; - } + NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; + asn_dec_rval_t dec_rval; + int rval=0; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN); + // LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size, + // NR_UE_rrc_inst[ue_mod_idP].Info[gNB_index].State); + dec_rval = uper_decode(NULL, + &asn_DEF_NR_DL_CCCH_Message, + (void **)&dl_ccch_msg, + (uint8_t *)Srb_info->Rx_buffer.Payload, + 100,0,0); + + // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg); + // } + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) { + LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); + return -1; + } + + if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) { + if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_SI_RECEIVED) { + switch (dl_ccch_msg->message.choice.c1->present) { + case NR_DL_CCCH_MessageType__c1_PR_NOTHING: + LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n", + ctxt_pP->module_id, + ctxt_pP->frame); + rval = 0; + break; + + case NR_DL_CCCH_MessageType__c1_PR_rrcReject: + LOG_I(NR_RRC, + "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n", + ctxt_pP->module_id, + ctxt_pP->frame); + rval = 0; + break; + + case NR_DL_CCCH_MessageType__c1_PR_rrcSetup: + LOG_I(NR_RRC, + "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n", + ctxt_pP->module_id, + ctxt_pP->frame, + ctxt_pP->rnti); + // Get configuration + // Release T300 timer + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0; + + nr_rrc_ue_process_masterCellGroup( + ctxt_pP, + gNB_index, + &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup); + nr_sa_rrc_ue_process_radioBearerConfig( + ctxt_pP, + gNB_index, + &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); + nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED); + nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED); + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti; + rrc_ue_generate_RRCSetupComplete( + ctxt_pP, + gNB_index, + dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier, + NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); + rval = 0; + break; + + default: + LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n", + ctxt_pP->module_id, + ctxt_pP->frame); + rval = -1; + break; } } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); - return rval; - + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); + return rval; } // from NR SRB3 int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message( - const module_id_t module_id, - const uint8_t gNB_index, - const uint8_t *bufferP, - const uint32_t buffer_len ){ - // uper_decode by nr R15 rrc_connection_reconfiguration - - int32_t i; - NR_DL_DCCH_Message_t *nr_dl_dcch_msg = NULL; - MessageDef *msg_p; + const module_id_t module_id, + const uint8_t gNB_index, + const uint8_t *bufferP, + const uint32_t buffer_len ){ + // uper_decode by nr R15 rrc_connection_reconfiguration + + int32_t i; + NR_DL_DCCH_Message_t *nr_dl_dcch_msg = NULL; + MessageDef *msg_p; - asn_dec_rval_t dec_rval = uper_decode( NULL, - &asn_DEF_NR_DL_DCCH_Message, - (void**)&nr_dl_dcch_msg, - (uint8_t *)bufferP, - buffer_len, 0, 0); + asn_dec_rval_t dec_rval = uper_decode( NULL, + &asn_DEF_NR_DL_DCCH_Message, + (void**)&nr_dl_dcch_msg, + (uint8_t *)bufferP, + buffer_len, 0, 0); - if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { + if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { + for (i=0; imessage.present){ + case NR_DL_DCCH_MessageType_PR_c1: + switch(nr_dl_dcch_msg->message.choice.c1->present){ + case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: + nr_rrc_ue_process_rrcReconfiguration(module_id,nr_dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration); + break; - printf("\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 ); - return -1; - } - - if(nr_dl_dcch_msg != NULL){ - switch(nr_dl_dcch_msg->message.present){ - case NR_DL_DCCH_MessageType_PR_c1: - - switch(nr_dl_dcch_msg->message.choice.c1->present){ - case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: - nr_rrc_ue_process_rrcReconfiguration(nr_dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration); - break; - - case NR_DL_DCCH_MessageType__c1_PR_NOTHING: - case NR_DL_DCCH_MessageType__c1_PR_rrcResume: - case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: - msg_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_CONN_RELEASE_IND); - - if((nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) && - (nr_dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){ - nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer = - NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; - nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType = - NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; - } - itti_send_msg_to_task(TASK_RRC_NRUE,module_id,msg_p); - break; - case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: - case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: - case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: - case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: - case NR_DL_DCCH_MessageType__c1_PR_counterCheck: - case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: - case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: - case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: - case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16: - case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16: - case NR_DL_DCCH_MessageType__c1_PR_spare3: - case NR_DL_DCCH_MessageType__c1_PR_spare2: - case NR_DL_DCCH_MessageType__c1_PR_spare1: - default: - // not supported or unused - break; - } - break; - case NR_DL_DCCH_MessageType_PR_NOTHING: - case NR_DL_DCCH_MessageType_PR_messageClassExtension: - default: - // not supported or unused - break; + case NR_DL_DCCH_MessageType__c1_PR_NOTHING: + case NR_DL_DCCH_MessageType__c1_PR_rrcResume: + case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: + msg_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_CONN_RELEASE_IND); + if((nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) && + (nr_dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){ + nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; + nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; + } + itti_send_msg_to_task(TASK_RRC_NRUE,module_id,msg_p); + break; + + case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: + case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: + case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: + case NR_DL_DCCH_MessageType__c1_PR_counterCheck: + case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: + case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: + case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16: + case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16: + case NR_DL_DCCH_MessageType__c1_PR_spare3: + case NR_DL_DCCH_MessageType__c1_PR_spare2: + case NR_DL_DCCH_MessageType__c1_PR_spare1: + default: + // not supported or unused + break; } - - // release memory allocation - SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 ); - }else{ - // log.. + break; + case NR_DL_DCCH_MessageType_PR_NOTHING: + case NR_DL_DCCH_MessageType_PR_messageClassExtension: + default: + // not supported or unused + break; } + + // release memory allocation + SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 ); + }else{ + // log.. + } - return 0; - + return 0; } @@ -1628,11 +1620,11 @@ nr_rrc_ue_process_securityModeCommand( } LOG_D(NR_RRC,"[UE %d] security mode is %x \n",ctxt_pP->module_id, securityMode); - NR_UE_rrc_inst->cipheringAlgorithm = + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm = securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm; - NR_UE_rrc_inst->integrityProtAlgorithm = + NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm = *securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm; -memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); + memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); //memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t)); ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; ul_dcch_msg.message.choice.c1 = calloc(1, sizeof(*ul_dcch_msg.message.choice.c1)); @@ -1666,22 +1658,22 @@ memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); "%02x%02x%02x%02x" "%02x%02x%02x%02x" "%02x%02x%02x%02x\n", - NR_UE_rrc_inst->kgnb[0], NR_UE_rrc_inst->kgnb[1], NR_UE_rrc_inst->kgnb[2], NR_UE_rrc_inst->kgnb[3], - NR_UE_rrc_inst->kgnb[4], NR_UE_rrc_inst->kgnb[5], NR_UE_rrc_inst->kgnb[6], NR_UE_rrc_inst->kgnb[7], - NR_UE_rrc_inst->kgnb[8], NR_UE_rrc_inst->kgnb[9], NR_UE_rrc_inst->kgnb[10], NR_UE_rrc_inst->kgnb[11], - NR_UE_rrc_inst->kgnb[12], NR_UE_rrc_inst->kgnb[13], NR_UE_rrc_inst->kgnb[14], NR_UE_rrc_inst->kgnb[15], - NR_UE_rrc_inst->kgnb[16], NR_UE_rrc_inst->kgnb[17], NR_UE_rrc_inst->kgnb[18], NR_UE_rrc_inst->kgnb[19], - NR_UE_rrc_inst->kgnb[20], NR_UE_rrc_inst->kgnb[21], NR_UE_rrc_inst->kgnb[22], NR_UE_rrc_inst->kgnb[23], - NR_UE_rrc_inst->kgnb[24], NR_UE_rrc_inst->kgnb[25], NR_UE_rrc_inst->kgnb[26], NR_UE_rrc_inst->kgnb[27], - NR_UE_rrc_inst->kgnb[28], NR_UE_rrc_inst->kgnb[29], NR_UE_rrc_inst->kgnb[30], NR_UE_rrc_inst->kgnb[31]); - derive_key_rrc_enc(NR_UE_rrc_inst->cipheringAlgorithm,NR_UE_rrc_inst->kgnb, &kRRCenc); - derive_key_rrc_int(NR_UE_rrc_inst->integrityProtAlgorithm,NR_UE_rrc_inst->kgnb, &kRRCint); - derive_key_up_enc(NR_UE_rrc_inst->cipheringAlgorithm,NR_UE_rrc_inst->kgnb, &kUPenc); + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]); + derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc); + derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint); + derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc); if (securityMode != 0xff) { pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0, - NR_UE_rrc_inst->cipheringAlgorithm - | (NR_UE_rrc_inst->integrityProtAlgorithm << 4), + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm + | (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), kRRCenc, kRRCint, kUPenc); } else { LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", @@ -1696,7 +1688,7 @@ memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); ul_dcch_msg.message.choice.c1->choice.securityModeComplete->rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier; ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.present = NR_SecurityModeComplete__criticalExtensions_PR_securityModeComplete; ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_IEs_t)); - ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete->nonCriticalExtension =NULL; + ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete->nonCriticalExtension =NULL; LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (gNB %d), rrc_TransactionIdentifier: %ld\n", ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index, securityModeCommand->rrc_TransactionIdentifier); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, @@ -1719,17 +1711,17 @@ memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); LOG_T(NR_RRC, "\n"); #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_UE_SIM,TASK_RRC_GNB_SIM, - (enc_rval.encoded + 7) / 8); - memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8); + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_UE_SIM,TASK_RRC_GNB_SIM, + (enc_rval.encoded + 7) / 8); + memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8); - message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, UE_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); + message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, UE_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); #else rrc_data_req ( ctxt_pP, @@ -1740,7 +1732,8 @@ memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); buffer, PDCP_TRANSMISSION_MODE_CONTROL); #endif - } else LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n", + } else + LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n", securityModeCommand->criticalExtensions.present); } @@ -1803,12 +1796,12 @@ nr_rrc_ue_establish_srb1( ) //----------------------------------------------------------------------------- { - // add descriptor from RRC PDU - NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Active = 1; - NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG - NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Srb_info.Srb_id = 1; - LOG_I(NR_RRC, "[UE %d], CONFIG_SRB1 %d corresponding to gNB_index %d\n", ue_mod_idP, DCCH, gNB_index); - return(0); + // add descriptor from RRC PDU + NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Active = 1; + NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG + NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Srb_info.Srb_id = 1; + LOG_I(NR_RRC, "[UE %d], CONFIG_SRB1 %d corresponding to gNB_index %d\n", ue_mod_idP, DCCH, gNB_index); + return(0); } //----------------------------------------------------------------------------- @@ -1848,31 +1841,31 @@ nr_rrc_ue_establish_drb( LOG_I(NR_RRC,"[UE %d] Frame %d: processing RRCReconfiguration: reconfiguring DRB %ld\n", ue_mod_idP, frameP, DRB_config->drb_Identity); - if(!AMF_MODE_ENABLED) { - ip_addr_offset3 = 0; - ip_addr_offset4 = 1; - LOG_I(OIP, "[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, - ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1); - oip_ifup = nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id - UE_NAS_USE_TUN?1:(ip_addr_offset3+ue_mod_idP+1), // third_octet - ip_addr_offset4+ue_mod_idP+1, // fourth_octet - "oip"); // interface suffix (when using kernel module) + if(!AMF_MODE_ENABLED) { + ip_addr_offset3 = 0; + ip_addr_offset4 = 1; + LOG_I(OIP, "[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, + ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1); + oip_ifup = nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id + UE_NAS_USE_TUN?1:(ip_addr_offset3+ue_mod_idP+1), // third_octet + ip_addr_offset4+ue_mod_idP+1, // fourth_octet + "oip"); // interface suffix (when using kernel module) - if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB - LOG_I(OIP, "[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n", - ue_mod_idP, - ip_addr_offset3+ue_mod_idP, - (long int)((gNB_index * NR_maxDRB) + DRB_config->drb_Identity)); - rb_conf_ipv4(0,//add - ue_mod_idP,//cx align with the UE index - ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index - (gNB_index * NR_maxDRB) + DRB_config->drb_Identity,//rb - 0,//dscp - ipv4_address(ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1),//saddr - ipv4_address(ip_addr_offset3+ue_mod_idP+1, gNB_index+1));//daddr - LOG_D(NR_RRC,"[UE %d] State = Attached (gNB %d)\n",ue_mod_idP,gNB_index); - } + if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB + LOG_I(OIP, "[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n", + ue_mod_idP, + ip_addr_offset3+ue_mod_idP, + (long int)((gNB_index * NR_maxDRB) + DRB_config->drb_Identity)); + rb_conf_ipv4(0,//add + ue_mod_idP,//cx align with the UE index + ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index + (gNB_index * NR_maxDRB) + DRB_config->drb_Identity,//rb + 0,//dscp + ipv4_address(ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1),//saddr + ipv4_address(ip_addr_offset3+ue_mod_idP+1, gNB_index+1));//daddr + LOG_D(NR_RRC,"[UE %d] State = Attached (gNB %d)\n",ue_mod_idP,gNB_index); } + } return(0); } @@ -1886,119 +1879,119 @@ nr_rrc_ue_process_measConfig( ) //----------------------------------------------------------------------------- { - int i; - long ind; - NR_MeasObjectToAddMod_t *measObj = NULL; - NR_ReportConfigToAddMod_t *reportConfig = NULL; + int i; + long ind; + NR_MeasObjectToAddMod_t *measObj = NULL; + NR_ReportConfigToAddMod_t *reportConfig = NULL; - if (measConfig->measObjectToRemoveList != NULL) { - for (i = 0; i < measConfig->measObjectToRemoveList->list.count; i++) { - ind = *measConfig->measObjectToRemoveList->list.array[i]; - free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]); + if (measConfig->measObjectToRemoveList != NULL) { + for (i = 0; i < measConfig->measObjectToRemoveList->list.count; i++) { + ind = *measConfig->measObjectToRemoveList->list.array[i]; + free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]); + } + } + + if (measConfig->measObjectToAddModList != NULL) { + LOG_I(NR_RRC, "Measurement Object List is present\n"); + for (i = 0; i < measConfig->measObjectToAddModList->list.count; i++) { + measObj = measConfig->measObjectToAddModList->list.array[i]; + ind = measConfig->measObjectToAddModList->list.array[i]->measObjectId; + + if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]) { + LOG_D(NR_RRC, "Modifying measurement object %ld\n",ind); + memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1], + (char *)measObj, + sizeof(NR_MeasObjectToAddMod_t)); + } else { + LOG_I(NR_RRC, "Adding measurement object %ld\n", ind); + + if (measObj->measObject.present == NR_MeasObjectToAddMod__measObject_PR_measObjectNR) { + NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]=measObj; } + } } - if (measConfig->measObjectToAddModList != NULL) { - LOG_I(NR_RRC, "Measurement Object List is present\n"); - for (i = 0; i < measConfig->measObjectToAddModList->list.count; i++) { - measObj = measConfig->measObjectToAddModList->list.array[i]; - ind = measConfig->measObjectToAddModList->list.array[i]->measObjectId; + LOG_I(NR_RRC, "call rrc_mac_config_req \n"); + // rrc_mac_config_req_ue + } - if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]) { - LOG_D(NR_RRC, "Modifying measurement object %ld\n",ind); - memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1], - (char *)measObj, - sizeof(NR_MeasObjectToAddMod_t)); - } else { - LOG_I(NR_RRC, "Adding measurement object %ld\n", ind); + if (measConfig->reportConfigToRemoveList != NULL) { + for (i = 0; i < measConfig->reportConfigToRemoveList->list.count; i++) { + ind = *measConfig->reportConfigToRemoveList->list.array[i]; + free(NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]); + } + } - if (measObj->measObject.present == NR_MeasObjectToAddMod__measObject_PR_measObjectNR) { - NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]=measObj; - } - } + if (measConfig->reportConfigToAddModList != NULL) { + LOG_I(NR_RRC,"Report Configuration List is present\n"); + for (i = 0; i < measConfig->reportConfigToAddModList->list.count; i++) { + ind = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId; + reportConfig = measConfig->reportConfigToAddModList->list.array[i]; + + if (NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]) { + LOG_I(NR_RRC, "Modifying Report Configuration %ld\n", ind-1); + memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1], + (char *)measConfig->reportConfigToAddModList->list.array[i], + sizeof(NR_ReportConfigToAddMod_t)); + } else { + LOG_D(RRC,"Adding Report Configuration %ld %p \n", ind-1, measConfig->reportConfigToAddModList->list.array[i]); + if (reportConfig->reportConfig.present == NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR) { + NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i]; } - - LOG_I(NR_RRC, "call rrc_mac_config_req \n"); - // rrc_mac_config_req_ue + } } + } - if (measConfig->reportConfigToRemoveList != NULL) { - for (i = 0; i < measConfig->reportConfigToRemoveList->list.count; i++) { - ind = *measConfig->reportConfigToRemoveList->list.array[i]; - free(NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]); - } + if (measConfig->measIdToRemoveList != NULL) { + for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) { + ind = *measConfig->measIdToRemoveList->list.array[i]; + free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]); } + } - if (measConfig->reportConfigToAddModList != NULL) { - LOG_I(NR_RRC,"Report Configuration List is present\n"); - for (i = 0; i < measConfig->reportConfigToAddModList->list.count; i++) { - ind = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId; - reportConfig = measConfig->reportConfigToAddModList->list.array[i]; + if (measConfig->measIdToAddModList != NULL) { + for (i = 0; i < measConfig->measIdToAddModList->list.count; i++) { + ind = measConfig->measIdToAddModList->list.array[i]->measId; - if (NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]) { - LOG_I(NR_RRC, "Modifying Report Configuration %ld\n", ind-1); - memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1], - (char *)measConfig->reportConfigToAddModList->list.array[i], - sizeof(NR_ReportConfigToAddMod_t)); - } else { - LOG_D(RRC,"Adding Report Configuration %ld %p \n", ind-1, measConfig->reportConfigToAddModList->list.array[i]); - if (reportConfig->reportConfig.present == NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR) { - NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i]; - } - } - } + if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]) { + LOG_D(NR_RRC, "Modifying Measurement ID %ld\n",ind-1); + memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1], + (char *)measConfig->measIdToAddModList->list.array[i], + sizeof(NR_MeasIdToAddMod_t)); + } else { + LOG_D(NR_RRC, "Adding Measurement ID %ld %p\n", ind-1, measConfig->measIdToAddModList->list.array[i]); + NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i]; + } } + } - if (measConfig->measIdToRemoveList != NULL) { - for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) { - ind = *measConfig->measIdToRemoveList->list.array[i]; - free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]); - } + if (measConfig->quantityConfig != NULL) { + if (NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index]) { + LOG_D(RRC,"Modifying Quantity Configuration \n"); + memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index], + (char *)measConfig->quantityConfig, + sizeof(NR_QuantityConfig_t)); + } else { + LOG_D(NR_RRC, "Adding Quantity configuration\n"); + NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index] = measConfig->quantityConfig; } + } - if (measConfig->measIdToAddModList != NULL) { - for (i = 0; i < measConfig->measIdToAddModList->list.count; i++) { - ind = measConfig->measIdToAddModList->list.array[i]->measId; - - if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]) { - LOG_D(NR_RRC, "Modifying Measurement ID %ld\n",ind-1); - memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1], - (char *)measConfig->measIdToAddModList->list.array[i], - sizeof(NR_MeasIdToAddMod_t)); - } else { - LOG_D(NR_RRC, "Adding Measurement ID %ld %p\n", ind-1, measConfig->measIdToAddModList->list.array[i]); - NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i]; - } - } + if (measConfig->measGapConfig != NULL) { + if (NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index]) { + memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index], + (char *)measConfig->measGapConfig, + sizeof(NR_MeasGapConfig_t)); + } else { + NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index] = measConfig->measGapConfig; } + } - if (measConfig->quantityConfig != NULL) { - if (NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index]) { - LOG_D(RRC,"Modifying Quantity Configuration \n"); - memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index], - (char *)measConfig->quantityConfig, - sizeof(NR_QuantityConfig_t)); - } else { - LOG_D(NR_RRC, "Adding Quantity configuration\n"); - NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index] = measConfig->quantityConfig; - } - } - - if (measConfig->measGapConfig != NULL) { - if (NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index]) { - memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index], - (char *)measConfig->measGapConfig, - sizeof(NR_MeasGapConfig_t)); - } else { - NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index] = measConfig->measGapConfig; - } - } - - if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_ssb_RSRP) { - NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.ssb_RSRP; - } else if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_csi_RSRP) { - NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.csi_RSRP; - } + if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_ssb_RSRP) { + NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.ssb_RSRP; + } else if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_csi_RSRP) { + NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.csi_RSRP; + } } //----------------------------------------------------------------------------- @@ -2010,156 +2003,155 @@ nr_sa_rrc_ue_process_radioBearerConfig( ) //----------------------------------------------------------------------------- { - long SRB_id, DRB_id; - int i, cnt; + long SRB_id, DRB_id; + int i, cnt; - if( radioBearerConfig->srb3_ToRelease != NULL){ - if( *radioBearerConfig->srb3_ToRelease == TRUE){ - //TODO (release the PDCP entity and the srb-Identity of the SRB3.) + if( radioBearerConfig->srb3_ToRelease != NULL){ + if( *radioBearerConfig->srb3_ToRelease == TRUE){ + //TODO (release the PDCP entity and the srb-Identity of the SRB3.) + } + } + + if (radioBearerConfig->srb_ToAddModList != NULL) { + if (radioBearerConfig->securityConfig != NULL) { + if (*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master) { + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm = + radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm; + NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm = + *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm; } } - if (radioBearerConfig->srb_ToAddModList != NULL) { + uint8_t *kRRCenc = NULL; + uint8_t *kRRCint = NULL; + derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc); + derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint); + // Refresh SRBs + // nr_rrc_pdcp_config_asn1_req(ctxt_pP, + // radioBearerConfig->srb_ToAddModList, + // NULL, + // NULL, + // NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | + // (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), + // kRRCenc, + // kRRCint, + // NULL, + // NULL, + // NULL, + // NULL); + // Refresh SRBs + // nr_rrc_rlc_config_asn1_req(ctxt_pP, + // radioBearerConfig->srb_ToAddModList, + // NULL, + // NULL, + // NULL, + // NULL + // ); - if (radioBearerConfig->securityConfig != NULL) { - if (*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master) { - NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm = - radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm; - NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm = - *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm; - } + for (cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) { + SRB_id = radioBearerConfig->srb_ToAddModList->list.array[cnt]->srb_Identity; + LOG_D(NR_RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n", ctxt_pP->module_id, ctxt_pP->frame, cnt, SRB_id); + if (SRB_id == 1) { + if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index]) { + memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index], + radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t)); + } else { + NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt]; + nr_rrc_ue_establish_srb1(ctxt_pP->module_id, + ctxt_pP->frame, + gNB_index, + radioBearerConfig->srb_ToAddModList->list.array[cnt]); + + LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n", + ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); + // rrc_mac_config_req_ue } + } else { + if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index]) { + memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index], + radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t)); + } else { + NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt]; + nr_rrc_ue_establish_srb2(ctxt_pP->module_id, + ctxt_pP->frame, + gNB_index, + radioBearerConfig->srb_ToAddModList->list.array[cnt]); - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc); - derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint); - // Refresh SRBs - // nr_rrc_pdcp_config_asn1_req(ctxt_pP, - // radioBearerConfig->srb_ToAddModList, - // NULL, - // NULL, - // NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | - // (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), - // kRRCenc, - // kRRCint, - // NULL, - // NULL, - // NULL, - // NULL); - // Refresh SRBs - // nr_rrc_rlc_config_asn1_req(ctxt_pP, - // radioBearerConfig->srb_ToAddModList, - // NULL, - // NULL, - // NULL, - // NULL - // ); - - for (cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) { - SRB_id = radioBearerConfig->srb_ToAddModList->list.array[cnt]->srb_Identity; - LOG_D(NR_RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n", ctxt_pP->module_id, ctxt_pP->frame, cnt, SRB_id); - if (SRB_id == 1) { - if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index]) { - memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index], - radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t)); - } else { - NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt]; - nr_rrc_ue_establish_srb1(ctxt_pP->module_id, - ctxt_pP->frame, - gNB_index, - radioBearerConfig->srb_ToAddModList->list.array[cnt]); - - LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n", - ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); - // rrc_mac_config_req_ue - } - } else { - if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index]) { - memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index], - radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t)); - } else { - NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt]; - nr_rrc_ue_establish_srb2(ctxt_pP->module_id, - ctxt_pP->frame, - gNB_index, - radioBearerConfig->srb_ToAddModList->list.array[cnt]); - - LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n", - ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); - // rrc_mac_config_req_ue - } - } // srb2 + LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n", + ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); + // rrc_mac_config_req_ue } - } // srb_ToAddModList + } // srb2 + } + } // srb_ToAddModList - // Establish DRBs if present - if (radioBearerConfig->drb_ToAddModList != NULL) { - if ((NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB == NULL) && - (radioBearerConfig->drb_ToAddModList->list.count >= 1)) { - NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t)); - *NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity; - } - - for (cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) { - DRB_id = radioBearerConfig->drb_ToAddModList->list.array[cnt]->drb_Identity; - if (NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]) { - memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1], - radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t)); - } else { - LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]); - NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt]; - } - } - - uint8_t *kUPenc = NULL; - derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc); - MSC_LOG_TX_MESSAGE( - MSC_RRC_UE, - MSC_PDCP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security %X)", - MSC_AS_TIME_ARGS(ctxt_pP), - ctxt_pP->rnti, - NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | - (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4)); - - // Refresh DRBs - // nr_rrc_pdcp_config_asn1_req(ctxt_pP, - // NULL, - // radioBearerConfig->drb_ToAddModList, - // NULL, - // NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | - // (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), - // NULL, - // NULL, - // kUPenc, - // NULL, - // NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB, - // NULL); - // Refresh DRBs - // nr_rrc_rlc_config_asn1_req(ctxt_pP, - // NULL, - // radioBearerConfig->drb_ToAddModList, - // NULL, - // NULL, - // NULL - // ); - } // drb_ToAddModList - - if (radioBearerConfig->drb_ToReleaseList != NULL) { - for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) { - DRB_id = *radioBearerConfig->drb_ToReleaseList->list.array[i]; - free(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]); - } + // Establish DRBs if present + if (radioBearerConfig->drb_ToAddModList != NULL) { + if ((NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB == NULL) && + (radioBearerConfig->drb_ToAddModList->list.count >= 1)) { + NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t)); + *NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity; } - NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED; - LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index); + for (cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) { + DRB_id = radioBearerConfig->drb_ToAddModList->list.array[cnt]->drb_Identity; + if (NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]) { + memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1], + radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t)); + } else { + LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]); + NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt]; + } + } + + uint8_t *kUPenc = NULL; + derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc); + MSC_LOG_TX_MESSAGE( + MSC_RRC_UE, + MSC_PDCP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security %X)", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt_pP->rnti, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | + (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4)); + + // Refresh DRBs + // nr_rrc_pdcp_config_asn1_req(ctxt_pP, + // NULL, + // radioBearerConfig->drb_ToAddModList, + // NULL, + // NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | + // (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), + // NULL, + // NULL, + // kUPenc, + // NULL, + // NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB, + // NULL); + // Refresh DRBs + // nr_rrc_rlc_config_asn1_req(ctxt_pP, + // NULL, + // radioBearerConfig->drb_ToAddModList, + // NULL, + // NULL, + // NULL + // ); + } // drb_ToAddModList + + if (radioBearerConfig->drb_ToReleaseList != NULL) { + for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) { + DRB_id = *radioBearerConfig->drb_ToReleaseList->list.array[i]; + free(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]); + } + } + + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED; + LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index); } //----------------------------------------------------------------------------- @@ -2171,44 +2163,44 @@ rrc_ue_process_rrcReconfiguration( ) //----------------------------------------------------------------------------- { - LOG_I(NR_RRC, "[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCReconfiguration (gNB %d)\n", - ctxt_pP->module_id, ctxt_pP->frame, gNB_index); + LOG_I(NR_RRC, "[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCReconfiguration (gNB %d)\n", + ctxt_pP->module_id, ctxt_pP->frame, gNB_index); - NR_RRCReconfiguration_IEs_t *ie = NULL; + NR_RRCReconfiguration_IEs_t *ie = NULL; - if (rrcReconfiguration->criticalExtensions.present - == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration) { - ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration; - if (ie->measConfig != NULL) { - LOG_I(NR_RRC, "Measurement Configuration is present\n"); - nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig); - } - - if (ie->radioBearerConfig != NULL) { - LOG_I(NR_RRC, "radio Bearer Configuration is present\n"); - nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig); - } - - /* Check if there is dedicated NAS information to forward to NAS */ - if (ie->nonCriticalExtension->dedicatedNAS_MessageList != NULL) { - int list_count; - uint32_t pdu_length; - uint8_t *pdu_buffer; - MessageDef *msg_p; - - for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) { - pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size; - pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf; - msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_ESTABLI_CNF); - NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS; - NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length; - NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer; - itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); - } - - free (ie->nonCriticalExtension->dedicatedNAS_MessageList); - } + if (rrcReconfiguration->criticalExtensions.present + == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration) { + ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration; + if (ie->measConfig != NULL) { + LOG_I(NR_RRC, "Measurement Configuration is present\n"); + nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig); } + + if (ie->radioBearerConfig != NULL) { + LOG_I(NR_RRC, "radio Bearer Configuration is present\n"); + nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig); + } + + /* Check if there is dedicated NAS information to forward to NAS */ + if (ie->nonCriticalExtension->dedicatedNAS_MessageList != NULL) { + int list_count; + uint32_t pdu_length; + uint8_t *pdu_buffer; + MessageDef *msg_p; + + for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) { + pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size; + pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf; + msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_ESTABLI_CNF); + NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS; + NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length; + NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer; + itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); + } + + free (ie->nonCriticalExtension->dedicatedNAS_MessageList); + } + } } //----------------------------------------------------------------------------- @@ -2261,97 +2253,97 @@ nr_rrc_ue_decode_dcch( ) //----------------------------------------------------------------------------- { - asn_dec_rval_t dec_rval; - NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; - MessageDef *msg_p; + asn_dec_rval_t dec_rval; + NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; + MessageDef *msg_p; - if (Srb_id != 1) { - LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n", - ctxt_pP->module_id, ctxt_pP->frame, Srb_id); - return -1; - } else { - LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id); + if (Srb_id != 1) { + LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n", + ctxt_pP->module_id, ctxt_pP->frame, Srb_id); + return -1; + } else { + LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id); + } + + LOG_D(NR_RRC, "Decoding DL-DCCH Message\n"); + dec_rval = uper_decode( NULL, + &asn_DEF_NR_DL_DCCH_Message, + (void **)&dl_dcch_msg, + Buffer, + RRC_BUF_SIZE, + 0, + 0); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed); + return -1; + } + + // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message,(void *)dl_dcch_msg); + // } + + if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) { + switch (dl_dcch_msg->message.choice.c1->present) { + case NR_DL_DCCH_MessageType__c1_PR_NOTHING: + LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n"); + break; + + case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: + rrc_ue_process_rrcReconfiguration(ctxt_pP, + dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration, + gNB_indexP); + nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP, + gNB_indexP, + dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier); + break; + + case NR_DL_DCCH_MessageType__c1_PR_rrcResume: + case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: + msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_RELEASE_IND); + + if((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) && + (dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){ + dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; + dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; + } + + itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); + break; + case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: + LOG_I(RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", + ctxt_pP->module_id,gNB_indexP); + nr_rrc_ue_process_ueCapabilityEnquiry( + ctxt_pP, + dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry, + gNB_indexP); + break; + case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: + case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: + case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: + case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16: + case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16: + case NR_DL_DCCH_MessageType__c1_PR_spare3: + case NR_DL_DCCH_MessageType__c1_PR_spare2: + case NR_DL_DCCH_MessageType__c1_PR_spare1: + case NR_DL_DCCH_MessageType__c1_PR_counterCheck: + break; + case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: + LOG_I(RRC, "[UE %d] Received securityModeCommand (gNB %d)\n", + ctxt_pP->module_id, gNB_indexP); + nr_rrc_ue_process_securityModeCommand( + ctxt_pP, + dl_dcch_msg->message.choice.c1->choice.securityModeCommand, + gNB_indexP); + + break; } - - LOG_D(NR_RRC, "Decoding DL-DCCH Message\n"); - dec_rval = uper_decode( NULL, - &asn_DEF_NR_DL_DCCH_Message, - (void **)&dl_dcch_msg, - Buffer, - RRC_BUF_SIZE, - 0, - 0); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed); - return -1; - } - - // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message,(void *)dl_dcch_msg); - // } - - if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) { - switch (dl_dcch_msg->message.choice.c1->present) { - case NR_DL_DCCH_MessageType__c1_PR_NOTHING: - LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n"); - break; - - case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: - rrc_ue_process_rrcReconfiguration(ctxt_pP, - dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration, - gNB_indexP); - nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP, - gNB_indexP, - dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier); - break; - - case NR_DL_DCCH_MessageType__c1_PR_rrcResume: - case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: - msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_RELEASE_IND); - - if((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) && - (dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){ - dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer = - NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; - dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType = - NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; - } - - itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); - break; - case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: - LOG_I(RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", - ctxt_pP->module_id,gNB_indexP); - nr_rrc_ue_process_ueCapabilityEnquiry( - ctxt_pP, - dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry, - gNB_indexP); - break; - case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: - case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: - case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: - case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: - case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: - case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16: - case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16: - case NR_DL_DCCH_MessageType__c1_PR_spare3: - case NR_DL_DCCH_MessageType__c1_PR_spare2: - case NR_DL_DCCH_MessageType__c1_PR_spare1: - case NR_DL_DCCH_MessageType__c1_PR_counterCheck: - break; - case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: - LOG_I(RRC, "[UE %d] Received securityModeCommand (gNB %d)\n", - ctxt_pP->module_id, gNB_indexP); - nr_rrc_ue_process_securityModeCommand( - ctxt_pP, - dl_dcch_msg->message.choice.c1->choice.securityModeCommand, - gNB_indexP); - - break; - } - } - return 0; + } + return 0; } //----------------------------------------------------------------------------- @@ -2435,7 +2427,7 @@ void *rrc_nrue_task( void *args_p ) { LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); break; } - LOG_I(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id)); + LOG_I(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id)); result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); msg_p = NULL; @@ -2449,17 +2441,17 @@ void nr_rrc_ue_process_sidelink_radioResourceConfig( { //process sl_CommConfig, configure MAC/PHY for transmitting SL communication (RRC_CONNECTED) if (sl_ConfigDedicatedNR != NULL) { - switch (sl_ConfigDedicatedNR->present){ + switch (sl_ConfigDedicatedNR->present){ case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_setup: - //TODO - break; + //TODO + break; case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_release: - break; + break; case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_NOTHING: - break; + break; default: - break; - } + break; + } } } @@ -2548,17 +2540,17 @@ nr_rrc_ue_process_ueCapabilityEnquiry( LOG_I(RRC,"UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_UE_SIM,TASK_RRC_GNB_SIM, - (enc_rval.encoded + 7) / 8); - memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8); - - message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, UE_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_UE_SIM,TASK_RRC_GNB_SIM, + (enc_rval.encoded + 7) / 8); + memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8); + + message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, UE_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); #else rrc_data_req_ue ( ctxt_pP, diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 207ba02f81..cb1c6a117f 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -59,12 +59,12 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char*); \param size length of buffer*/ //TODO check to use which one //int8_t nr_rrc_ue_decode_rrcReconfiguration(const uint8_t *buffer, const uint32_t size); -int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const uint8_t *buffer, const uint32_t size); +int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, const uint8_t *buffer, const uint32_t size); /**\brief Process NR RRC connection reconfiguration via SRB3 \param rrcReconfiguration decoded rrc connection reconfiguration*/ -int8_t nr_rrc_ue_process_rrcReconfiguration(NR_RRCReconfiguration_t *rrcReconfiguration); +int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration); /**\prief Process measurement config from NR RRC connection reconfiguration message \param meas_config measurement configuration*/ @@ -73,7 +73,7 @@ int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config); /**\prief Process secondary cell group config from NR RRC connection reconfiguration message or EN-DC primitives \param cell_group_config secondary cell group configuration*/ //TODO check EN-DC function call flow. -int8_t nr_rrc_ue_process_scg_config(NR_CellGroupConfig_t *cell_group_config); +int8_t nr_rrc_ue_process_scg_config(const module_id_t module_id, NR_CellGroupConfig_t *cell_group_config); /**\prief Process radio bearer config from NR RRC connection reconfiguration message \param radio_bearer_config radio bearer configuration*/ diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c index a09c6207af..d9352f2d0a 100644 --- a/openair2/SIMULATION/NR_RRC/itti_sim.c +++ b/openair2/SIMULATION/NR_RRC/itti_sim.c @@ -1,12 +1,32 @@ -/*! -\file itti_sim.c +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file itti_sim.c + * \brief simulator for itti message from node to UE + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ -\brief simulator for itti message from node to UE -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ #include diff --git a/openair2/UTIL/OPT/mac_pcap.h b/openair2/UTIL/OPT/mac_pcap.h index 3141d17d59..c443ceb1fb 100644 --- a/openair2/UTIL/OPT/mac_pcap.h +++ b/openair2/UTIL/OPT/mac_pcap.h @@ -6,6 +6,7 @@ #include #define MAC_LTE_DLT 147 +#define DLT_IPV4 228 /********************************************************/ /* Definitions and descriptions come from: http://wiki.wireshark.org/Development/LibpcapFileFormat */ @@ -29,20 +30,4 @@ typedef struct pcaprec_hdr_s { unsigned int orig_len; /* actual length of packet */ } pcaprec_hdr_t; -/* Context information for every MAC PDU that will be logged */ -typedef struct MAC_Context_Info_t { - unsigned short radioType; - unsigned char direction; - unsigned char rntiType; - unsigned short rnti; - unsigned short ueid; - unsigned char isRetx; - unsigned char crcStatusOK; - - unsigned short sysFrameNumber; - unsigned short subFrameNumber; - - unsigned int subframesSinceCaptureStart; -} MAC_Context_Info_t; - #endif diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h index 6861e09cb1..ab591d3a65 100644 --- a/openair2/UTIL/OPT/opt.h +++ b/openair2/UTIL/OPT/opt.h @@ -73,7 +73,7 @@ typedef guint8 gboolean; /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------*/ #define OPT_PARAMS_DESC { \ - {"type" , CONFIG_HLP_TYPEMON, 0, strptr:&in_type, defstrval:"none", TYPE_STRING, 0}, \ + {"type" , CONFIG_HLP_TYPEMON, 0, strptr:(char**)&in_type, defstrval:"none", TYPE_STRING, 0}, \ {"ip" , CONFIG_HLP_L2MONIP, 0, strptr:(char**)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ {"path" , CONFIG_HLP_L2MONPATH, 0, strptr:(char**)&in_path,defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, 0}, \ } diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index 8c6a74e042..3f416c9255 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -90,6 +90,7 @@ what about the implementation #include #include +#include #include "common/config/config_userapi.h" #include "opt.h" #include "common/utils/system.h" @@ -99,8 +100,6 @@ int opt_enabled=0; //static unsigned char g_PDUBuffer[1600]; //static unsigned int g_PDUOffset; -static char in_ip[128]={0}; -static char in_path[128]={0}; FILE *file_fd = NULL; pcap_hdr_t file_header = { 0xa1b2c3d4, /* magic number */ @@ -108,10 +107,14 @@ pcap_hdr_t file_header = { 0, /* timezone */ 0, /* sigfigs - apparently all tools do this */ 65535, /* snaplen - this should be long enough */ - MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */ + DLT_IPV4 + //MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */ }; trace_mode_t opt_type = OPT_NONE; +static char *in_type=NULL; +static char *in_path=NULL; +static char *in_ip=NULL; static unsigned int subframesSinceCaptureStart; static int g_socksd = -1;/* UDP socket used for sending frames */ @@ -131,8 +134,80 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, guint8 oob_event, guint8 oob_event_value, uint8_t *pdu_buffer, unsigned int pdu_buffer_size); -static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context, - const unsigned char *PDU, unsigned int length); +unsigned short checksum(unsigned short *ptr, int length) { + int sum = 0; + u_short answer = 0; + unsigned short *w = ptr; + int nleft = length; + + while(nleft > 1) { + sum += *w++; + nleft -= 2; + } + + sum = (sum >> 16) + (sum & 0xFFFF); + sum += (sum >> 16); + answer = ~sum; + return(answer); +} + +/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */ +static int MAC_LTE_PCAP_WritePDU(const uint8_t *PDU, + unsigned int length) { + pcaprec_hdr_t packet_header; + // IPv4 header + typedef struct ip_hdr { + unsigned char ip_verlen; // 4-bit IPv4 version 4-bit header length (in 32-bit words) + unsigned char ip_tos; // IP type of service + unsigned short ip_totallength; // Total length + unsigned short ip_id; // Unique identifier + unsigned short ip_offset; // Fragment offset field + unsigned char ip_ttl; // Time to live + unsigned char ip_protocol; // Protocol(TCP,UDP etc) + unsigned short ip_checksum; // IP checksum + unsigned int ip_srcaddr; // Source address + unsigned int ip_destaddr; // Source address + } IPV4_HDR; + // Define the UDP header + typedef struct udp_hdr { + unsigned short src_portno; // Source port no. + unsigned short dst_portno; // Dest. port no. + unsigned short udp_length; // Udp packet length + unsigned short udp_checksum; // Udp checksum (optional) + } UDP_HDR; + IPV4_HDR IPheader= {0}; + IPheader.ip_verlen = (4 << 4) | (sizeof(IPV4_HDR) / sizeof(uint32_t)); + IPheader.ip_totallength = htons(sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length); + IPheader.ip_ttl = 8; // Time-to-live is eight + IPheader.ip_protocol = IPPROTO_UDP; + IPheader.ip_srcaddr = inet_addr(in_ip); + IPheader.ip_destaddr = inet_addr(in_ip); + IPheader.ip_checksum = checksum((unsigned short *)&IPheader, sizeof(IPV4_HDR)); + // Initialize the UDP header + UDP_HDR UDPheader; + UDPheader.src_portno = htons( PACKET_MAC_LTE_DEFAULT_UDP_PORT); + UDPheader.dst_portno = htons( PACKET_MAC_LTE_DEFAULT_UDP_PORT); + UDPheader.udp_length = htons(sizeof(UDP_HDR) + length); + UDPheader.udp_checksum = 0; + /****************************************************************/ + /* PCAP Header */ + /* TODO: Timestamp might want to be relative to a more sensible + base time... */ + struct timeval tv; + gettimeofday(&tv, NULL); + packet_header.ts_sec = tv.tv_sec; + packet_header.ts_usec = tv.tv_usec; + packet_header.incl_len =sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length; + packet_header.orig_len =sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length; + /***************************************************************/ + /* Now write everything to the file */ + fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, file_fd); + fwrite(&IPheader, sizeof(IPV4_HDR), 1, file_fd); + fwrite(&UDPheader, sizeof(UDP_HDR), 1, file_fd); + fwrite(PDU, 1, length, file_fd); + fflush(file_fd); + return length; +} static void *opt_listener_thread(void *arg) { ssize_t ret; @@ -198,7 +273,6 @@ int opt_create_listener_socket(char *ip_address, uint16_t port) { } threadCreate(&opt_listener.thread, opt_listener_thread, NULL, "flexran", -1, OAI_PRIORITY_RT_LOW); - return 0; } @@ -321,67 +395,20 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, frameOffset += pdu_buffer_size; } - /* Send out the data over the UDP socket */ - bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0, - (const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr)); + if ( opt_type == OPT_WIRESHARK ) + /* Send out the data over the UDP socket */ + bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0, + (const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr)); + else + bytesSent = MAC_LTE_PCAP_WritePDU(frameBuffer, frameOffset); if (bytesSent != frameOffset) { - LOG_W(OPT, "sendto() failed (not a thread-safe func)- expected %d bytes, got %ld (errno=%d)\n", + LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n", frameOffset, bytesSent, errno); //exit(1); } } -/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */ -static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context, - const uint8_t *PDU, - unsigned int length) -{ - pcaprec_hdr_t packet_header; - uint8_t context_header[256]; - int offset = 0; - unsigned short tmp16; - /*****************************************************************/ - /* Context information (same as written by UDP heuristic clients */ - context_header[offset++] = context->radioType; - context_header[offset++] = context->direction; - context_header[offset++] = context->rntiType; - /* RNTI */ - context_header[offset++] = MAC_LTE_RNTI_TAG; - tmp16 = htons(context->rnti); - memcpy(context_header+offset, &tmp16, 2); - offset += 2; - /* UEId */ - context_header[offset++] = MAC_LTE_UEID_TAG; - tmp16 = htons(context->ueid); - memcpy(context_header+offset, &tmp16, 2); - offset += 2; - /* Subframe number */ - context_header[offset++] = MAC_LTE_FRAME_SUBFRAME_TAG; - tmp16 = htons(context->subFrameNumber); - memcpy(context_header+offset, &tmp16, 2); - offset += 2; - /* CRC Status */ - context_header[offset++] = MAC_LTE_CRC_STATUS_TAG; - context_header[offset++] = context->crcStatusOK; - /* Data tag immediately preceding PDU */ - context_header[offset++] = MAC_LTE_PAYLOAD_TAG; - /****************************************************************/ - /* PCAP Header */ - /* TODO: Timestamp might want to be relative to a more sensible - base time... */ - packet_header.ts_sec = context->subframesSinceCaptureStart / 1000; - packet_header.ts_usec = (context->subframesSinceCaptureStart % 1000) * 1000; - packet_header.incl_len = offset + length; - packet_header.orig_len = offset + length; - /***************************************************************/ - /* Now write everything to the file */ - fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, file_fd); - fwrite(context_header, 1, offset, file_fd); - fwrite(PDU, 1, length, file_fd); - return 1; -} - #include extern RAN_CONTEXT_t RC; #include @@ -389,7 +416,6 @@ extern RAN_CONTEXT_t RC; void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event, int oob_event_value) { - MAC_Context_Info_t pdu_context; int radioType=FDD_RADIO; LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n", direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber); @@ -405,53 +431,41 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p switch (opt_type) { case OPT_WIRESHARK : - if (g_socksd == -1) { + if (g_socksd == -1) return; - } - SendFrame( radioType, - (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK, - rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber, - 1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus - oob_event,oob_event_value, - pdu_buffer, pdu_buffer_size); break; case OPT_PCAP: - if (file_fd == NULL) { + if (file_fd == NULL) return; - } - pdu_context.radioType = radioType; - pdu_context.direction = (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK - : DIRECTION_UPLINK; - pdu_context.rntiType = rntiType; - pdu_context.rnti = rnti; - pdu_context.ueid = ueid; - pdu_context.isRetx = 0; - pdu_context.crcStatusOK =1; - pdu_context.sysFrameNumber = sysFrameNumber; - pdu_context.subFrameNumber = subFrameNumber; - pdu_context.subframesSinceCaptureStart = subframesSinceCaptureStart++; - MAC_LTE_PCAP_WritePDU( &pdu_context, pdu_buffer, pdu_buffer_size); break; case OPT_TSHARK: default: + return; break; } + + SendFrame( radioType, + (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK, + rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber, + 1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus + oob_event,oob_event_value, + pdu_buffer, pdu_buffer_size); } + /*---------------------------------------------------*/ -int init_opt(void) -{ - char *in_type=NULL; +int init_opt(void) { + in_type=malloc(200); + in_ip=malloc(200); + in_path=malloc(200); paramdef_t opt_params[] = OPT_PARAMS_DESC ; checkedparam_t opt_checkParams[] = OPTPARAMS_CHECK_DESC; - uint16_t in_port=0; config_set_checkfunctions(opt_params, opt_checkParams, sizeof(opt_params)/sizeof(paramdef_t)); config_get( opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX); - subframesSinceCaptureStart = 0; int tmptype = config_get_processedint( &(opt_params[OPTTYPE_IDX])); @@ -462,25 +476,21 @@ int init_opt(void) } else if (tmptype == OPT_PCAP && strlen(in_path) > 0) { opt_type = OPT_PCAP; opt_enabled=1; - LOG_I(OPT,"Enabling OPT for PCAP with the following file %s \n",in_path); } else if (tmptype == OPT_WIRESHARK && strlen(in_ip) > 0) { opt_enabled=1; opt_type = OPT_WIRESHARK; - LOG_I(OPT,"Enabling OPT for wireshark for local interface %s\n",in_ip); } else { LOG_E(OPT,"Invalid OPT configuration\n"); config_printhelp(opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX); } - in_port = PACKET_MAC_LTE_DEFAULT_UDP_PORT; - // trace_mode switch (opt_type) { case OPT_WIRESHARK: - + LOG_I(OPT,"mode Wireshark: ip %s port %d\n", in_ip, PACKET_MAC_LTE_DEFAULT_UDP_PORT); /* Create local server socket only if using localhost address */ - if (strcmp(in_ip, "127.0.0.1") == 0) { - opt_create_listener_socket(in_ip, in_port); + if (strncmp(in_ip, "127.0.0.1", 4) == 0) { + opt_create_listener_socket(in_ip, PACKET_MAC_LTE_DEFAULT_UDP_PORT); } g_socksd = socket(AF_INET, SOCK_DGRAM, 0); @@ -493,11 +503,12 @@ int init_opt(void) /* Get remote IP address from the function argument */ g_serv_addr.sin_family = AF_INET; - g_serv_addr.sin_port = htons(in_port); + g_serv_addr.sin_port = htons(PACKET_MAC_LTE_DEFAULT_UDP_PORT); g_serv_addr.sin_addr.s_addr = inet_addr(in_ip); break; case OPT_PCAP: + LOG_I(OPT,"mode PCAB : path is %s \n",in_path); file_fd = fopen(in_path, "w"); if (file_fd == NULL) { @@ -516,19 +527,9 @@ int init_opt(void) default: opt_type = OPT_NONE; - LOG_W(OPT, "supported Option\n"); + LOG_E(OPT,"Unsupported or unknown mode %d \n", opt_type); break; } - - if ( opt_type == OPT_WIRESHARK ) - LOG_E(OPT,"mode Wireshark: ip %s port %d\n", in_ip, in_port); - else if (opt_type == OPT_PCAP) - LOG_E(OPT,"mode PCAB : path is %s \n",in_path); - else - LOG_E(OPT,"Unsupported or unknown mode %d \n", opt_type); - - // mac_info = (mac_info*)malloc16(sizeof(mac_lte_info)); - // memset(mac_info, 0, sizeof(mac_lte_info)+pdu_buffer_size + 8); return (1); } diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c b/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c index 23404e0ed1..3d177c396a 100644 --- a/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c @@ -1,11 +1,31 @@ -/*! \file RegistrationRequest.c +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ -\brief registration request procedures for gNB -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ +/*! \file RegistrationRequest.c + * \brief registration request procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ #include #include diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.h b/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.h index fdc70fa57d..ce534bfff9 100644 --- a/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.h +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.h @@ -1,11 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + /*! \file RegistrationRequest.h + * \brief registration request procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ -\brief registration request procedures for gNB -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ #include #include diff --git a/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.c b/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.c index c0203f9882..e3b4bd021a 100644 --- a/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.c +++ b/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.c @@ -1,3 +1,25 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + /*! \file ExtendedProtocolDiscriminator.c \brief Extended protocol discriminator for registration request procedures diff --git a/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.h b/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.h index 1fb3e085c7..3bf1f6ec8f 100644 --- a/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.h +++ b/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.h @@ -1,3 +1,25 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + /*! \file ExtendedProtocolDiscriminator.h \brief Extended protocol discriminator for registration request procedures diff --git a/openair3/NAS/COMMON/IES/FGMMCapability.c b/openair3/NAS/COMMON/IES/FGMMCapability.c index b0796478f0..ce156e63bf 100644 --- a/openair3/NAS/COMMON/IES/FGMMCapability.c +++ b/openair3/NAS/COMMON/IES/FGMMCapability.c @@ -1,11 +1,31 @@ -/*! \file FGSMobileIdentity.c +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ -\brief 5GS Mobile Identity for registration request procedures -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ +/*! \file FGMMCapability.c + * \brief 5GS Mobile Identity for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ #include #include diff --git a/openair3/NAS/COMMON/IES/FGMMCapability.h b/openair3/NAS/COMMON/IES/FGMMCapability.h index c8cc238c80..d427896338 100644 --- a/openair3/NAS/COMMON/IES/FGMMCapability.h +++ b/openair3/NAS/COMMON/IES/FGMMCapability.h @@ -1,11 +1,32 @@ -/*! \file FGSMobileIdentity.h +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file FGMMCapability.h + * \brief 5GS Mobile Capability for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ -\brief 5GS Mobile Identity for registration request procedures -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ #include #include diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c index dfe19b4a35..cd7bee5bd7 100644 --- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c @@ -1,11 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + /*! \file FGSMobileIdentity.c + * \brief 5GS Mobile Identity for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ -\brief 5GS Mobile Identity for registration request procedures -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ #include #include diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h index 56e41767d7..40ca73c60b 100644 --- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h @@ -1,11 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + /*! \file FGSMobileIdentity.h + * \brief 5GS Mobile Identity for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ -\brief 5GS Mobile Identity for registration request procedures -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ #include #include diff --git a/openair3/NAS/COMMON/IES/FGSRegistrationType.c b/openair3/NAS/COMMON/IES/FGSRegistrationType.c index 9760238f10..7f1c3ae667 100644 --- a/openair3/NAS/COMMON/IES/FGSRegistrationType.c +++ b/openair3/NAS/COMMON/IES/FGSRegistrationType.c @@ -1,11 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + /*! \file FGSRegistrationType.c + * \brief 5GS Registration Type for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ -\brief 5GS Registration Type for registration request procedures -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ #include #include #include diff --git a/openair3/NAS/COMMON/IES/FGSRegistrationType.h b/openair3/NAS/COMMON/IES/FGSRegistrationType.h index 5e6e3ebc6e..a548d45d93 100644 --- a/openair3/NAS/COMMON/IES/FGSRegistrationType.h +++ b/openair3/NAS/COMMON/IES/FGSRegistrationType.h @@ -1,11 +1,31 @@ -/*! \file FGSRegistrationType.h +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ -\brief 5GS Registration Type for registration request procedures -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ +/*! \file FGSRegistrationType.h + * \brief 5GS Registration Type for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ #include #include #include diff --git a/openair3/NAS/COMMON/IES/NrUESecurityCapability.c b/openair3/NAS/COMMON/IES/NrUESecurityCapability.c index 964e226835..6c0ff7e7c7 100644 --- a/openair3/NAS/COMMON/IES/NrUESecurityCapability.c +++ b/openair3/NAS/COMMON/IES/NrUESecurityCapability.c @@ -1,11 +1,32 @@ -/*! \file FGSMobileIdentity.c +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file NrUESecurityCapability.c + * \brief 5GS UE Security Capability for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ -\brief 5GS Mobile Identity for registration request procedures -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ #include #include diff --git a/openair3/NAS/COMMON/IES/NrUESecurityCapability.h b/openair3/NAS/COMMON/IES/NrUESecurityCapability.h index a16b7c1c5c..10aa0cf0ea 100644 --- a/openair3/NAS/COMMON/IES/NrUESecurityCapability.h +++ b/openair3/NAS/COMMON/IES/NrUESecurityCapability.h @@ -1,11 +1,31 @@ -/*! \file FGSMobileIdentity.h +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ -\brief 5GS Mobile Identity for registration request procedures -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ +/*! \file NrUESecurityCapability.h + * \brief 5GS UE Security Capability for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ #include #include diff --git a/openair3/NAS/COMMON/IES/SpareHalfOctet.c b/openair3/NAS/COMMON/IES/SpareHalfOctet.c index afbb9f4f12..60c45e07c2 100644 --- a/openair3/NAS/COMMON/IES/SpareHalfOctet.c +++ b/openair3/NAS/COMMON/IES/SpareHalfOctet.c @@ -1,3 +1,25 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + /*! \file SpareHalfOctet.c \brief registration request procedures for gNB diff --git a/openair3/NAS/COMMON/IES/SpareHalfOctet.h b/openair3/NAS/COMMON/IES/SpareHalfOctet.h index f0f0b8047f..fbf410d4f8 100644 --- a/openair3/NAS/COMMON/IES/SpareHalfOctet.h +++ b/openair3/NAS/COMMON/IES/SpareHalfOctet.h @@ -1,3 +1,25 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + /*! \file SpareHalfOctet.h \brief registration request procedures for gNB diff --git a/openair3/NAS/COMMON/NR_NAS_defs.h b/openair3/NAS/COMMON/NR_NAS_defs.h new file mode 100644 index 0000000000..906c0cf504 --- /dev/null +++ b/openair3/NAS/COMMON/NR_NAS_defs.h @@ -0,0 +1,391 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#ifndef NR_NAS_DEFS_H +#define NR_NAS_DEFS_H + +#include +#include +#include + +/* TS 24.007 possible L3 formats: + Table 11.1: Formats of information elements + Format Meaning IEI present LI present Value part present + T Type only yes no no + V Value only no no yes + TV Type and Value yes no yes + LV Length and Value no yes yes + TLV Type, Length and Value yes yes yes + LV-E Length and Value no yes yes + TLV-E Type, Length and Value yes yes yes +*/ + +/* Map task id to printable name. */ +typedef struct { + int id; + char text[256]; +} text_info_t; + +static inline const char * idToText(const text_info_t* table, int size, int id) { + for(int i=0; i TS 24.007 +typedef enum { + SGSsessionmanagementmessages=0x2e, //LTEbox: 0xC0 ??? + SGSmobilitymanagementmessages=0x7e, +} Extendedprotocoldiscriminator_t; + +#define FOREACH_TYPE(TYPE_DEF) \ + TYPE_DEF( Registrationrequest,0x41 )\ +TYPE_DEF( Registrationaccept,0x42 )\ +TYPE_DEF( Registrationcomplete,0x43 )\ +TYPE_DEF( Registrationreject,0x44 )\ +TYPE_DEF( DeregistrationrequestUEoriginating,0x45 )\ +TYPE_DEF( DeregistrationacceptUEoriginating,0x46 )\ +TYPE_DEF( DeregistrationrequestUEterminated,0x47 )\ +TYPE_DEF( DeregistrationacceptUEterminated,0x48 )\ +TYPE_DEF( Servicerequest,0x4c )\ +TYPE_DEF( Servicereject,0x4d )\ +TYPE_DEF( Serviceaccept,0x4e )\ +TYPE_DEF( Controlplaneservicerequest,0x4f )\ +TYPE_DEF( Networkslicespecificauthenticationcommand,0x50 )\ +TYPE_DEF( Networkslicespecificauthenticationcomplete,0x51 )\ +TYPE_DEF( Networkslicespecificauthenticationresult,0x52 )\ +TYPE_DEF( Configurationupdatecommand,0x54 )\ +TYPE_DEF( Configurationupdatecomplete,0x55 )\ +TYPE_DEF( Authenticationrequest,0x56 )\ +TYPE_DEF( Authenticationresponse,0x57 )\ +TYPE_DEF( Authenticationreject,0x58 )\ +TYPE_DEF( Authenticationfailure,0x59 )\ +TYPE_DEF( Authenticationresult,0x5a )\ +TYPE_DEF( Identityrequest,0x5b )\ +TYPE_DEF( Identityresponse,0x5c )\ +TYPE_DEF( Securitymodecommand,0x5d )\ +TYPE_DEF( Securitymodecomplete,0x5e )\ +TYPE_DEF( Securitymodereject,0x5f )\ +TYPE_DEF( SGMMstatus,0x64 )\ +TYPE_DEF( Notification,0x65 )\ +TYPE_DEF( Notificationresponse,0x66 )\ +TYPE_DEF( ULNAStransport,0x67 )\ +TYPE_DEF( DLNAStransport,0x68 )\ +TYPE_DEF( PDUsessionestablishmentrequest,0xc1 )\ +TYPE_DEF( PDUsessionestablishmentaccept,0xc2 )\ +TYPE_DEF( PDUsessionestablishmentreject,0xc3 )\ +TYPE_DEF( PDUsessionauthenticationcommand,0xc5 )\ +TYPE_DEF( PDUsessionauthenticationcomplete,0xc6 )\ +TYPE_DEF( PDUsessionauthenticationresult,0xc7 )\ +TYPE_DEF( PDUsessionmodificationrequest,0xc9 )\ +TYPE_DEF( PDUsessionmodificationreject,0xca )\ +TYPE_DEF( PDUsessionmodificationcommand,0xcb )\ +TYPE_DEF( PDUsessionmodificationcomplete,0xcc )\ +TYPE_DEF( PDUsessionmodificationcommandreject,0xcd )\ +TYPE_DEF( PDUsessionreleaserequest,0xd1 )\ +TYPE_DEF( PDUsessionreleasereject,0xd2 )\ +TYPE_DEF( PDUsessionreleasecommand,0xd3 )\ +TYPE_DEF( PDUsessionreleasecomplete,0xd4 )\ +TYPE_DEF( SGSMstatus,0xd6 )\ + +static const text_info_t message_text_info[] = { + FOREACH_TYPE(TO_TEXT) +}; + +//! Tasks id of each task +typedef enum { + FOREACH_TYPE(TO_ENUM) +} SGSmobilitymanagementmessages_t; + +// TS 24.501 +typedef enum { + notsecurityprotected=0, + Integrityprotected=1, + Integrityprotectedandciphered=2, + Integrityprotectedwithnew5GNASsecuritycontext=3, + Integrityprotectedandcipheredwithnew5GNASsecuritycontext=4, +} Security_header_t; + +typedef enum { + SUCI=1, + SGGUTI, + IMEI, + SGSTMSI, + IMEISV, + MACaddress, + EUI64, +} identitytype_t; + + +// table 9.11.3.2.1 +#define FOREACH_CAUSE(CAUSE_DEF) \ + CAUSE_DEF(Illegal_UE,0x3 )\ + CAUSE_DEF(PEI_not_accepted,0x5 )\ + CAUSE_DEF(Illegal_ME,0x6 )\ + CAUSE_DEF(SGS_services_not_allowed,0x7 )\ + CAUSE_DEF(UE_identity_cannot_be_derived_by_the_network,0x9 )\ + CAUSE_DEF(Implicitly_de_registered,0x0a )\ + CAUSE_DEF(PLMN_not_allowed,0x0b )\ + CAUSE_DEF(Tracking_area_not_allowed,0x0c )\ + CAUSE_DEF(Roaming_not_allowed_in_this_tracking_area,0x0d )\ + CAUSE_DEF(No_suitable_cells_in_tracking_area,0x0f )\ + CAUSE_DEF(MAC_failure,0x14 )\ + CAUSE_DEF(Synch_failure,0x15 )\ + CAUSE_DEF(Congestion,0x16 )\ + CAUSE_DEF(UE_security_capabilities_mismatch,0x17 )\ + CAUSE_DEF(Security_mode_rejected_unspecified,0x18 )\ + CAUSE_DEF(Non_5G_authentication_unacceptable,0x1a )\ + CAUSE_DEF(N1_mode_not_allowed,0x1b )\ + CAUSE_DEF(Restricted_service_area,0x1c )\ + CAUSE_DEF(Redirection_to_EPC_required,0x1f )\ + CAUSE_DEF(LADN_not_available,0x2b )\ + CAUSE_DEF(No_network_slices_available,0x3e )\ + CAUSE_DEF(Maximum_number_of_PDU_sessions_reached,0x41 )\ + CAUSE_DEF(Insufficient_resources_for_specific_slice_and_DNN,0x43 )\ + CAUSE_DEF(Insufficient_resources_for_specific_slice,0x45 )\ + CAUSE_DEF(ngKSI_already_in_use,0x47 )\ + CAUSE_DEF(Non_3GPP_access_to_5GCN_not_allowed,0x48 )\ + CAUSE_DEF(Serving_network_not_authorized,0x49 )\ + CAUSE_DEF(Temporarily_not_authorized_for_this_SNPN,0x4A )\ + CAUSE_DEF(Permanently_not_authorized_for_this_SNPN,0x4b )\ + CAUSE_DEF(Not_authorized_for_this_CAG_or_authorized_for_CAG_cells_only,0x4c )\ + CAUSE_DEF(Wireline_access_area_not_allowed,0x4d )\ + CAUSE_DEF(Payload_was_not_forwarded,0x5a )\ + CAUSE_DEF(DNN_not_supported_or_not_subscribed_in_the_slice,0x5b )\ + CAUSE_DEF(Insufficient_user_plane_resources_for_the_PDU_session,0x5c )\ + CAUSE_DEF(Semantically_incorrect_message,0x5f )\ + CAUSE_DEF(Invalid_mandatory_information,0x60 )\ + CAUSE_DEF(Message_type_non_existent_or_not_implemented,0x61 )\ + CAUSE_DEF(Message_type_not_compatible_with_the_protocol_state,0x62 )\ + CAUSE_DEF(Information_element_non_existent_or_not_implemented,0x63 )\ + CAUSE_DEF(Conditional_IE_error,0x64 )\ + CAUSE_DEF(Message_not_compatible_with_the_protocol_state,0x65 )\ + CAUSE_DEF(Protocol_error_unspecified,0x67 ) + +/* Map task id to printable name. */ + +#define CAUSE_TEXT(LabEl, nUmID) {nUmID, #LabEl}, + +static const text_info_t cause_text_info[] = { + FOREACH_CAUSE(TO_TEXT) +}; + +#define CAUSE_ENUM(LabEl, nUmID ) LabEl = nUmID, +//! Tasks id of each task +typedef enum { + FOREACH_CAUSE(TO_ENUM) +} cause_id_t; + +//_table_9.11.4.2.1:_5GSM_cause_information_element +#define FOREACH_CAUSE_SECU(CAUSE_SECU_DEF) \ + CAUSE_SECU_DEF(Security_Operator_determined_barring,0x08 )\ + CAUSE_SECU_DEF(Security_Insufficient_resources,0x1a )\ + CAUSE_SECU_DEF(Security_Missing_or_unknown_DNN,0x1b )\ + CAUSE_SECU_DEF(Security_Unknown_PDU_session_type,0x1c )\ + CAUSE_SECU_DEF(Security_User_authentication_or_authorization_failed,0x1d )\ + CAUSE_SECU_DEF(Security_Request_rejected_unspecified,0x1f )\ + CAUSE_SECU_DEF(Security_Service_option_not_supported,0x20 )\ + CAUSE_SECU_DEF(Security_Requested_service_option_not_subscribed,0x21 )\ + CAUSE_SECU_DEF(Security_Service_option_temporarily_out_of_order,0x22 )\ + CAUSE_SECU_DEF(Security_PTI_already_in_use,0x23 )\ + CAUSE_SECU_DEF(Security_Regular_deactivation,0x24 )\ + CAUSE_SECU_DEF(Security_Network_failure,0x26 )\ + CAUSE_SECU_DEF(Security_Reactivation_requested,0x27 )\ + CAUSE_SECU_DEF(Security_Semantic_error_in_the_TFT_operation,0x29 )\ + CAUSE_SECU_DEF(Security_Syntactical_error_in_the_TFT_operation,0x2a )\ + CAUSE_SECU_DEF(Security_Invalid_PDU_session_identity,0x2b )\ + CAUSE_SECU_DEF(Security_Semantic_errors_in_packet_filter,0x2c )\ + CAUSE_SECU_DEF(Security_Syntactical_error_in_packet_filter,0x2d )\ + CAUSE_SECU_DEF(Security_Out_of_LADN_service_area,0x2e )\ + CAUSE_SECU_DEF(Security_PTI_mismatch,0x2f )\ + CAUSE_SECU_DEF(Security_PDU_session_type_IPv4_only_allowed,0x32 )\ + CAUSE_SECU_DEF(Security_PDU_session_type_IPv6_only_allowed,0x33 )\ + CAUSE_SECU_DEF(Security_PDU_session_does_not_exist,0x36 )\ + CAUSE_SECU_DEF(Security_PDU_session_type_IPv4v6_only_allowed,0x39 )\ + CAUSE_SECU_DEF(Security_PDU_session_type_Unstructured_only_allowed,0x3a )\ + CAUSE_SECU_DEF(Security_PDU_session_type_Ethernet_only_allowed,0x3d )\ + CAUSE_SECU_DEF(Security_Insufficient_resources_for_specific_slice_and_DNN,0x43 )\ + CAUSE_SECU_DEF(Security_Not_supported_SSC_mode,0x44 )\ + CAUSE_SECU_DEF(Security_Insufficient_resources_for_specific_slice,0x45 )\ + CAUSE_SECU_DEF(Security_Missing_or_unknown_DNN_in_a_slice,0x46 )\ + CAUSE_SECU_DEF(Security_Invalid_PTI_value,0x51 )\ + CAUSE_SECU_DEF(Security_Maximum_data_rate_per_UE_for_user_plane_integrity_protection_is_too_low,0x52 )\ + CAUSE_SECU_DEF(Security_Semantic_error_in_the_QoS_operation,0x53 )\ + CAUSE_SECU_DEF(Security_Syntactical_error_in_the_QoS_operation,0x54 )\ + CAUSE_SECU_DEF(Security_Invalid_mapped_EPS_bearer_identity,0x55 )\ + CAUSE_SECU_DEF(Security_Semantically_incorrect_message,0x5f )\ + CAUSE_SECU_DEF(Security_Invalid_mandatory_information,0x60 )\ + CAUSE_SECU_DEF(Security_Message_type_non_existent_or_not_implemented,0x61 )\ + CAUSE_SECU_DEF(Security_Message_type_not_compatible_with_the_protocol_state,0x62 )\ + CAUSE_SECU_DEF(Security_Information_element_non_existent_or_not_implemented,0x63 )\ + CAUSE_SECU_DEF(Security_Conditional_IE_error,0x64 )\ + CAUSE_SECU_DEF(Security_Message_not_compatible_with_the_protocol_state,0x65 )\ + CAUSE_SECU_DEF(Security_Protocol_error_unspecified,0x6f ) + +static const text_info_t cause_secu_text_info[] = { + FOREACH_CAUSE_SECU(TO_TEXT) +}; + +//! Tasks id of each task +typedef enum { + FOREACH_CAUSE_SECU(TO_ENUM) +} cause_secu_id_t; + +// IEI (information element identifier) are spread in each message definition +#define IEI_RAND 0x21 +#define IEI_AUTN 0x20 +#define IEI_EAP 0x78 +#define IEI_AuthenticationResponse 0x2d + +//TS 24.501 sub layer states for UE +// for network side, only 5GMMderegistered, 5GMMderegistered_initiated, 5GMMregistered, 5GMMservice_request_initiated are valid +typedef enum { + SGMMnull, + SGMMderegistered, + SGMMderegistered_initiated, + SGMMregistered, + SGMMregistered_initiated, + SGMMservice_request_initiated, +} SGMM_UE_states; + +typedef struct { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; +} SGScommonHeader_t; + +typedef struct { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; + identitytype_t it:8; +} Identityrequest_t; + +// the message continues with the identity value, depending on identity type, see TS 14.501, 9.11.3.4 +typedef struct __attribute__((packed)) { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; + uint16_t len; +} +Identityresponse_t; + +typedef struct __attribute__((packed)) { + Identityresponse_t common; + identitytype_t mi:8; + unsigned int supiFormat:4; + unsigned int identityType:4; + unsigned int mcc1:4; + unsigned int mcc2:4; + unsigned int mcc3:4; + unsigned int mnc3:4; + unsigned int mnc1:4; + unsigned int mnc2:4; + unsigned int routing1:4; + unsigned int routing2:4; + unsigned int routing3:4; + unsigned int routing4:4; + unsigned int protectScheme:4; + unsigned int spare:4; + uint8_t hplmnId; +} +IdentityresponseIMSI_t; + +typedef struct __attribute__((packed)) { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; + unsigned int ngKSI:4; + unsigned int spare:4; + unsigned int ABBALen:8; + unsigned int ABBA:16; + uint8_t ieiRAND; + uint8_t RAND[16]; + uint8_t ieiAUTN; + uint8_t AUTNlen; + uint8_t AUTN[16]; +} +authenticationrequestHeader_t; + +typedef struct __attribute__((packed)) { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; + uint8_t iei; + uint8_t RESlen; + uint8_t RES[16]; +} authenticationresponse_t; + +//AUTHENTICATION RESULT + +typedef struct __attribute__((packed)) { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; + + unsigned int selectedNASsecurityalgorithms; + unsigned int ngKSI:4; //ngKSI NAS key set identifier 9.11.3.32 + unsigned int spare:4; + // LV 3-9 bytes Replayed UE security capabilities UE security capability 9.11.3.54 + + /* optional + TV (E-, 1 byte) Oprional IMEISV request IMEISV request 9.11.3.28 + TV (57, 2 bytes ) Selected EPS NAS security algorithms EPS NAS security algorithms 9.11.3.25 + TLV (36, 3 bytes) Additional 5G security information Additional 5G security information 9.11.3.12 + TLV-E (78,, 7-1503 bytes) EAP message EAP message 9.11.2.2 + TLV (38, 4-n)ABBA ABBA 9.11.3.10 + TLV (19, 4-7) Replayed S1 UE security capabilities S1 UE security capability 9.11.3.48A + */ + +} securityModeCommand_t; + +typedef struct { + uicc_t *uicc; +} nr_user_nas_t; + +#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed") +#define myCalloc(var, type) type * var=(type*)calloc(sizeof(type),1); +#define arrayCpy(tO, FroM) STATIC_ASSERT(sizeof(tO) == sizeof(FroM)) ; memcpy(tO, FroM, sizeof(tO)) +int resToresStar(uint8_t *msg, uicc_t* uicc); + +int identityResponse(void **msg, nr_user_nas_t *UE); +int authenticationResponse(void **msg, nr_user_nas_t *UE); +void UEprocessNAS(void *msg,nr_user_nas_t *UE); +void SGSabortUE(void *msg, NRUEcontext_t *UE) ; +void SGSregistrationReq(void *msg, NRUEcontext_t *UE); +void SGSderegistrationUEReq(void *msg, NRUEcontext_t *UE); +void SGSauthenticationResp(void *msg, NRUEcontext_t *UE); +void SGSidentityResp(void *msg, NRUEcontext_t *UE); +void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE); +void SGSregistrationComplete(void *msg, NRUEcontext_t *UE); +void processNAS(void *msg, NRUEcontext_t *UE); +int identityRequest(void **msg, NRUEcontext_t *UE); +int authenticationRequest(void **msg, NRUEcontext_t *UE); +int securityModeCommand(void **msg, NRUEcontext_t *UE); + +#endif diff --git a/openair3/NAS/COMMON/milenage.h b/openair3/NAS/COMMON/milenage.h new file mode 100644 index 0000000000..c5762a0d69 --- /dev/null +++ b/openair3/NAS/COMMON/milenage.h @@ -0,0 +1,355 @@ +/* + Adaptatipn of SW from hereafter license + Author: laurent.thomas@open-cells.com + The OpenAirInterface project uses this copy under the terms of BSD + license. +*/ +/* + 3GPP AKA - Milenage algorithm (3GPP TS 35.205, .206, .207, .208) + Copyright (c) 2006-2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Alternatively, this software may be distributed under the terms of BSD + license. + + See README and COPYING for more details. + + This file implements an example authentication algorithm defined for 3GPP + AKA. This can be used to implement a simple HLR/AuC into hlr_auc_gw to allow + EAP-AKA to be tested properly with real USIM cards. + + This implementations assumes that the r1..r5 and c1..c5 constants defined in + TS 35.206 are used, i.e., r1=64, r2=0, r3=32, r4=64, r5=96, c1=00..00, + c2=00..01, c3=00..02, c4=00..04, c5=00..08. The block cipher is assumed to + be AES (Rijndael). +*/ + +#ifndef MILENAGE_H +#define MILENAGE_H +#include + + +#define u8 uint8_t +/** + milenage_f1 - Milenage f1 and f1* algorithms + @opc: OPc = 128-bit value derived from OP and K + @k: K = 128-bit subscriber key + @_rand: RAND = 128-bit random challenge + @sqn: SQN = 48-bit sequence number + @amf: AMF = 16-bit authentication management field + @mac_a: Buffer for MAC-A = 64-bit network authentication code, or %NULL + @mac_s: Buffer for MAC-S = 64-bit resync authentication code, or %NULL + Returns: true on success, false on failure +*/ + +void aes_128_encrypt_block(const u8* key, const u8* in, u8* out) { + AES_KEY k; + u8 tmp[16]; + AES_set_encrypt_key(key, 128, &k); + AES_encrypt(in, tmp, &k); + memcpy(out, tmp, sizeof(tmp)); +} +static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, + const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s) { + u8 tmp1[16], tmp2[16], tmp3[16]; + int i; + + /* tmp1 = TEMP = E_K(RAND XOR OP_C) */ + for (i = 0; i < 16; i++) + tmp1[i] = _rand[i] ^ opc[i]; + + aes_128_encrypt_block(k, tmp1, tmp1); + AES_KEY kTab; + uint8_t cyphered[16]; + AES_set_encrypt_key(k, 128, &kTab); + AES_encrypt(tmp1, cyphered, &kTab); + /* tmp2 = IN1 = SQN || AMF || SQN || AMF */ + memcpy(tmp2, sqn, 6); + memcpy(tmp2 + 6, amf, 2); + memcpy(tmp2 + 8, tmp2, 8); + + /* OUT1 = E_K(TEMP XOR rot(IN1 XOR OP_C, r1) XOR c1) XOR OP_C */ + + /* rotate (tmp2 XOR OP_C) by r1 (= 0x40 = 8 bytes) */ + for (i = 0; i < 16; i++) + tmp3[(i + 8) % 16] = tmp2[i] ^ opc[i]; + + /* XOR with TEMP = E_K(RAND XOR OP_C) */ + for (i = 0; i < 16; i++) + tmp3[i] ^= tmp1[i]; + + /* XOR with c1 (= ..00, i.e., NOP) */ + /* f1 || f1* = E_K(tmp3) XOR OP_c */ + aes_128_encrypt_block(k, tmp3, tmp1); + + for (i = 0; i < 16; i++) + tmp1[i] ^= opc[i]; + + if (mac_a) + memcpy(mac_a, tmp1, 8); /* f1 */ + + if (mac_s) + memcpy(mac_s, tmp1 + 8, 8); /* f1* */ + + return true; +} + + +/** + milenage_f2345 - Milenage f2, f3, f4, f5, f5* algorithms + @opc: OPc = 128-bit value derived from OP and K + @k: K = 128-bit subscriber key + @_rand: RAND = 128-bit random challenge + @res: Buffer for RES = 64-bit signed response (f2), or %NULL + @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL + @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL + @ak: Buffer for AK = 48-bit anonymity key (f5), or %NULL + @akstar: Buffer for AK = 48-bit anonymity key (f5*), or %NULL + Returns: true on success, false on failure +*/ +static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand, + u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar) { + u8 tmp1[16], tmp2[16], tmp3[16]; + int i; + + /* tmp2 = TEMP = E_K(RAND XOR OP_C) */ + for (i = 0; i < 16; i++) + tmp1[i] = _rand[i] ^ opc[i]; + + aes_128_encrypt_block(k, tmp1, tmp2); + + /* OUT2 = E_K(rot(TEMP XOR OP_C, r2) XOR c2) XOR OP_C */ + /* OUT3 = E_K(rot(TEMP XOR OP_C, r3) XOR c3) XOR OP_C */ + /* OUT4 = E_K(rot(TEMP XOR OP_C, r4) XOR c4) XOR OP_C */ + /* OUT5 = E_K(rot(TEMP XOR OP_C, r5) XOR c5) XOR OP_C */ + + /* f2 and f5 */ + /* rotate by r2 (= 0, i.e., NOP) */ + for (i = 0; i < 16; i++) + tmp1[i] = tmp2[i] ^ opc[i]; + + tmp1[15] ^= 1; /* XOR c2 (= ..01) */ + /* f5 || f2 = E_K(tmp1) XOR OP_c */ + aes_128_encrypt_block(k, tmp1, tmp3); + + for (i = 0; i < 16; i++) + tmp3[i] ^= opc[i]; + + if (res) + memcpy(res, tmp3 + 8, 8); /* f2 */ + + if (ak) + memcpy(ak, tmp3, 6); /* f5 */ + + /* f3 */ + if (ck) { + /* rotate by r3 = 0x20 = 4 bytes */ + for (i = 0; i < 16; i++) + tmp1[(i + 12) % 16] = tmp2[i] ^ opc[i]; + + tmp1[15] ^= 2; /* XOR c3 (= ..02) */ + aes_128_encrypt_block(k, tmp1, ck); + + for (i = 0; i < 16; i++) + ck[i] ^= opc[i]; + } + + /* f4 */ + if (ik) { + /* rotate by r4 = 0x40 = 8 bytes */ + for (i = 0; i < 16; i++) + tmp1[(i + 8) % 16] = tmp2[i] ^ opc[i]; + + tmp1[15] ^= 4; /* XOR c4 (= ..04) */ + aes_128_encrypt_block(k, tmp1, ik); + + for (i = 0; i < 16; i++) + ik[i] ^= opc[i]; + } + + /* f5* */ + if (akstar) { + /* rotate by r5 = 0x60 = 12 bytes */ + for (i = 0; i < 16; i++) + tmp1[(i + 4) % 16] = tmp2[i] ^ opc[i]; + + tmp1[15] ^= 8; /* XOR c5 (= ..08) */ + aes_128_encrypt_block(k, tmp1, tmp1); + + for (i = 0; i < 6; i++) + akstar[i] = tmp1[i] ^ opc[i]; + } + + return true; +} + + +/** + milenage_generate - Generate AKA AUTN,IK,CK,RES + @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) + @amf: AMF = 16-bit authentication management field + @k: K = 128-bit subscriber key + @sqn: SQN = 48-bit sequence number + @_rand: RAND = 128-bit random challenge + @autn: Buffer for AUTN = 128-bit authentication token + @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL + @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL + @res: Buffer for RES = 64-bit signed response (f2), or %NULL + @res_len: Max length for res; set to used length or 0 on failure +*/ +static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k, + const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik, + u8 *ck, u8 *res) { + int i; + u8 mac_a[8], ak[6]; + + if (!milenage_f1(opc, k, _rand, sqn, amf, mac_a, NULL) || + !milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) + return false; + + /* AUTN = (SQN ^ AK) || AMF || MAC */ + for (i = 0; i < 6; i++) + autn[i] = sqn[i] ^ ak[i]; + + memcpy(autn + 6, amf, 2); + memcpy(autn + 8, mac_a, 8); + return true; +} + + +/** + milenage_auts - Milenage AUTS validation + @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) + @k: K = 128-bit subscriber key + @_rand: RAND = 128-bit random challenge + @auts: AUTS = 112-bit authentication token from client + @sqn: Buffer for SQN = 48-bit sequence number + Returns: 0 = success (sqn filled), -1 on failure +*/ +#define p(a) printf("%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", (int)((a)[0]), (int)((a)[1]), (int)((a)[2]), (int)((a)[3]),(int)((a)[4]), (int)((a)[5])); +// valid code but put in comment as it is not used right now +#if 0 +static bool milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts, + u8 *sqn) { + u8 amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ + u8 ak[6], mac_s[8]; + int i; + + if (!milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak)) + return false; + + for (i = 0; i < 6; i++) + sqn[i] = auts[i] ^ ak[i]; + + //p(sqn); + if (!milenage_f1(opc, k, _rand, sqn, amf, NULL, mac_s) || + memcmp(mac_s, auts + 6, 8) != 0) + return false; + + return true; +} + + +/** + gsm_milenage - Generate GSM-Milenage (3GPP TS 55.205) authentication triplet + @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) + @k: K = 128-bit subscriber key + @_rand: RAND = 128-bit random challenge + @sres: Buffer for SRES = 32-bit SRES + @kc: Buffer for Kc = 64-bit Kc + Returns: 0 on success, -1 on failure +*/ +static bool gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc) { + u8 res[8], ck[16], ik[16]; + int i; + + if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL)) + return false; + + for (i = 0; i < 8; i++) + kc[i] = ck[i] ^ ck[i + 8] ^ ik[i] ^ ik[i + 8]; + +#ifdef GSM_MILENAGE_ALT_SRES + memcpy(sres, res, 4); +#else /* GSM_MILENAGE_ALT_SRES */ + + for (i = 0; i < 4; i++) + sres[i] = res[i] ^ res[i + 4]; + +#endif /* GSM_MILENAGE_ALT_SRES */ + return true; +} + + +/** + milenage_generate - Generate AKA AUTN,IK,CK,RES + @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) + @k: K = 128-bit subscriber key + @sqn: SQN = 48-bit sequence number + @_rand: RAND = 128-bit random challenge + @autn: AUTN = 128-bit authentication token + @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL + @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL + @res: Buffer for RES = 64-bit signed response (f2), or %NULL + @res_len: Variable that will be set to RES length + @auts: 112-bit buffer for AUTS + Returns: 0 on success, -1 on failure, or -2 on synchronization failure +*/ +static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand, + const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len, + u8 *auts) { + int i; + u8 mac_a[8], ak[6], rx_sqn[6]; + const u8 *amf; + + if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) + return -1; + + *res_len = 8; + + /* AUTN = (SQN ^ AK) || AMF || MAC */ + for (i = 0; i < 6; i++) + rx_sqn[i] = autn[i] ^ ak[i]; + + if (memcmp(rx_sqn, sqn, 6) <= 0) { + u8 auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ + + if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak)) + return -1; + + for (i = 0; i < 6; i++) + auts[i] = sqn[i] ^ ak[i]; + + if (milenage_f1(opc, k, _rand, sqn, auts_amf, NULL, auts + 6)) + return -1; + + return -2; + } + + amf = autn + 6; + + if (milenage_f1(opc, k, _rand, rx_sqn, amf, mac_a, NULL)) + return -1; + + if (memcmp(mac_a, autn + 8, 8) != 0) { + printf( "Milenage: MAC mismatch\n"); + return -1; + } + + return 0; +} + +static void milenage_opc_gen(const u8 *k, const u8 *op, u8 *opc) { + int i; + /* Encrypt OP using K */ + aes_128_encrypt_block(k, op, opc); + + /* XOR the resulting Ek(OP) with OP */ + for (i = 0; i < 16; i++) + opc[i] = opc[i] ^ op[i]; +} +#endif +#endif diff --git a/openair3/NAS/COMMON/nr_common.c b/openair3/NAS/COMMON/nr_common.c new file mode 100644 index 0000000000..736d75f6cc --- /dev/null +++ b/openair3/NAS/COMMON/nr_common.c @@ -0,0 +1,66 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include + +void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size) { + //SNN-network-identifier in TS 24.501 + // TS 24.501: If the MNC of the serving PLMN has two digits, then a zero is added at the beginning. + const char *format="5G:mnc000.mcc000.3gppnetwork.org"; + memcpy(msg,format, strlen(format)); + + if (nmc_size == 2) + memcpy(msg+7, imsiStr+3, 2); + else + memcpy(msg+6, imsiStr+3, 3); + + memcpy(msg+13, imsiStr, 3); +} + +int resToresStar(uint8_t *msg, uicc_t* uicc) { + // TS 33.220 annex B.2 => FC=0x6B in TS 33.501 annex A.4 + //input S to KDF + uint8_t S[128]= {0}; + S[0]=0x6B; + uint8_t *ptr=S+1; + servingNetworkName(ptr, uicc->imsiStr, uicc->nmc_size); + *(uint16_t *)(ptr+strlen((char *)ptr))=htons(strlen((char *)ptr)); + ptr+=strlen((char *)ptr)+sizeof(uint16_t); + // add rand + memcpy(ptr, uicc->rand, sizeof(uicc->rand) ) ; + *(uint16_t *)(ptr+sizeof(uicc->rand))=htons(sizeof(uicc->rand)); + ptr+=sizeof(uicc->rand)+sizeof(uint16_t); + // add res + memcpy(ptr, uicc->milenage_res, sizeof(uicc->milenage_res) ) ; + *(uint16_t *)(ptr+sizeof(uicc->milenage_res))=htons(sizeof(uicc->milenage_res)); + ptr+=sizeof(uicc->milenage_res)+sizeof(uint16_t); + // S is done + uint8_t ckik[sizeof(uicc->ck) +sizeof(uicc->ik)]; + memcpy(ckik, uicc->ck, sizeof(uicc->ck)); + memcpy(ckik+sizeof(uicc->ck),uicc->ik, sizeof(uicc->ik)); + uint8_t out[32]; + kdf(S, ptr-S, ckik, 32, out, sizeof(out)); + memcpy(msg, out+16, 16); + return 16; +} diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index b5fa230106..45ad298c11 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -1,12 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ /*! \file nr_nas_msg_sim.c + * \brief simulator for nr nas message + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ -\brief simulator for nr nas message -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ #include // memset #include // malloc, free diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index bc95047842..f77b9bafce 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -1,11 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + /*! \file nr_nas_msg_sim.h + * \brief simulator for nr nas message + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ -\brief simulator for nr nas message -\author Yoshio INOUE, Masayuki HARADA -\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com -\date 2020 -\version 0.1 -*/ #ifndef __NR_NAS_MSG_SIM_H__ diff --git a/openair3/NAS/NR_UE/ue_process_nas.c b/openair3/NAS/NR_UE/ue_process_nas.c new file mode 100644 index 0000000000..a89a07218e --- /dev/null +++ b/openair3/NAS/NR_UE/ue_process_nas.c @@ -0,0 +1,178 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#include +#include + + +void SGSabortNet(void *msg, nr_user_nas_t *UE) { +} + +void ue_nas_schedule(void) { +} + +/* + *Message reception + */ + +void SGSauthenticationReq(void *msg, nr_user_nas_t *UE) { + authenticationrequestHeader_t *amsg=(authenticationrequestHeader_t *) msg; + arrayCpy(UE->uicc->rand,amsg->RAND); + arrayCpy(UE->uicc->autn,amsg->AUTN); + // AUTHENTICATION REQUEST message that contains a valid ngKSI, SQN and MAC is received + // TBD verify ngKSI (we set it as '2', see gNB code) + // SQN and MAC are tested in auth resp processing + ue_nas_schedule(); +} + +void SGSidentityReq(void *msg, nr_user_nas_t *UE) { + Identityrequest_t *idmsg=(Identityrequest_t *) msg; + + if (idmsg->it == SUCI ) { + LOG_I(NAS,"Received Identity request, scheduling answer\n"); + ue_nas_schedule(); + } else + LOG_E(NAS,"Not developped: identity request for %d\n", idmsg->it); +} + +void SGSsecurityModeCommand(void *msg, nr_user_nas_t *UE) { +} + + +void UEprocessNAS(void *msg,nr_user_nas_t *UE) { + SGScommonHeader_t *header=(SGScommonHeader_t *) msg; + + if ( header->sh > 4 ) + SGSabortNet(msg, UE); + else { + switch (header->epd) { + case SGSmobilitymanagementmessages: + LOG_I(NAS,"Received message: %s\n", idStr(message_text_info, header->mt)); + + switch (header->mt) { + case Authenticationrequest: + SGSauthenticationReq(msg, UE); + break; + + case Identityrequest: + SGSidentityReq(msg, UE); + break; + + case Securitymodecommand: + SGSsecurityModeCommand(msg, UE); + break; + + default: + SGSabortNet(msg, UE); + } + + break; + + case SGSsessionmanagementmessages: + SGSabortNet(msg, UE); + break; + + default: + SGSabortNet(msg, UE); + } + } +} + +/* + * Messages emission + */ + +int identityResponse(void **msg, nr_user_nas_t *UE) { + if (UE->uicc == NULL) + // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE + UE->uicc=init_uicc("uicc"); + + // TS 24.501 9.11.3.4 + int imsiL=strlen(UE->uicc->imsiStr); + int msinL=imsiL-3-UE->uicc->nmc_size; + int respSize=sizeof(IdentityresponseIMSI_t) + (msinL+1)/2; + IdentityresponseIMSI_t *resp=(IdentityresponseIMSI_t *) calloc(respSize,1); + resp->common.epd=SGSmobilitymanagementmessages; + resp->common.sh=0; + resp->common.mt=Identityresponse; + resp->common.len=htons(respSize-sizeof(Identityresponse_t)); + resp->mi=SUCI; + resp->mcc1=UE->uicc->imsiStr[0]-'0'; + resp->mcc2=UE->uicc->imsiStr[1]-'0'; + resp->mcc3=UE->uicc->imsiStr[2]-'0'; + resp->mnc1=UE->uicc->imsiStr[3]-'0'; + resp->mnc2=UE->uicc->imsiStr[4]-'0'; + resp->mnc3=UE->uicc->nmc_size==2? 0xF : UE->uicc->imsiStr[3]-'0'; + // TBD: routing to fill (FF ?) + char *out=(char *)(resp+1); + char *ptr=UE->uicc->imsiStr + 3 + UE->uicc->nmc_size; + + while ( ptr < UE->uicc->imsiStr+strlen(UE->uicc->imsiStr) ) { + *out=((*(ptr+1)-'0')<<4) | (*(ptr) -'0'); + out++; + ptr+=2; + } + + if (msinL%2 == 1) + *out=((*(ptr-1)-'0')) | 0xF0; + + *msg=resp; + return respSize; +} + +int authenticationResponse(void **msg,nr_user_nas_t *UE) { + if (UE->uicc == NULL) + // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE + UE->uicc=init_uicc("uicc"); + + myCalloc(resp, authenticationresponse_t); + resp->epd=SGSmobilitymanagementmessages; + resp->sh=0; + resp->mt=Authenticationresponse; + resp->iei=IEI_AuthenticationResponse; + resp->RESlen=sizeof(resp->RES); // always 16 see TS 24.501 Table 8.2.2.1.1 + // Verify the AUTN + // a full implementation need to test several SQN + // as the last 5bits can be any value + // and the value can also be greater and accepted (if it is in the accepted window) + uint8_t AUTN[16]; + uicc_milenage_generate(AUTN, UE->uicc); + + if ( memcmp(UE->uicc->autn, AUTN, sizeof(AUTN)) == 0 ) { + // prepare and send good answer + resToresStar(resp->RES,UE->uicc); + } else { + // prepare and send autn is not compatible with our data + abort(); + } + + *msg=resp; + return sizeof(authenticationresponse_t); +} + +int securityModeComplete(void **msg, nr_user_nas_t *UE) { + return -1; +} + +int registrationComplete(void **msg, nr_user_nas_t *UE) { + return -1; +} diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index cd493dd09e..0c79fa3e3a 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -55,10 +55,6 @@ Description Defines functions used to handle EPS bearer contexts. #include #include #include -#ifdef UESIM_EXPANSION - #include "openairinterface5g_limits.h" - extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; -#endif /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -200,7 +196,7 @@ int esm_ebr_context_create( char *tmp = NULL; char ipv4_addr[INET_ADDRSTRLEN]; //char ipv6_addr[INET6_ADDRSTRLEN]; - char *netmask = NULL; + int netmask = 32; char broadcast[INET_ADDRSTRLEN]; struct in_addr in_addr; char command_line[500]; @@ -227,7 +223,7 @@ int esm_ebr_context_create( strcpy(ipv4_addr, tmp); if (IN_CLASSA(ntohl(in_addr.s_addr))) { - netmask = "255.0.0.0"; + netmask = 8; in_addr.s_addr = pdn->ip_addr[0] << 24 | ((255 << 16) & 0x00FF0000) | ((255 << 8) & 0x0000FF00) | @@ -239,7 +235,7 @@ int esm_ebr_context_create( // in_addr.s_addr); strcpy(broadcast, tmp); } else if (IN_CLASSB(ntohl(in_addr.s_addr))) { - netmask = "255.255.0.0"; + netmask = 16; in_addr.s_addr = pdn->ip_addr[0] << 24 | ((pdn->ip_addr[1] << 16) & 0x00FF0000) | ((255 << 8) & 0x0000FF00) | @@ -251,7 +247,7 @@ int esm_ebr_context_create( // in_addr.s_addr); strcpy(broadcast, tmp); } else if (IN_CLASSC(ntohl(in_addr.s_addr))) { - netmask = "255.255.255.0"; + netmask = 24; in_addr.s_addr = pdn->ip_addr[0] << 24 | ((pdn->ip_addr[1] << 16) & 0x00FF0000) | ((pdn->ip_addr[2] << 8) & 0x0000FF00) | @@ -263,56 +259,23 @@ int esm_ebr_context_create( // in_addr.s_addr); strcpy(broadcast, tmp); } else { - netmask = "255.255.255.255"; + netmask = 32; strcpy(broadcast, ipv4_addr); } - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { - // this is for L2 FAPI simulator. - // change for multiple UE's like 256UEs. - // if it's made too many tables , OS may crush so we use one table. - if(PDCP_USE_NETLINK) { -#ifdef UESIM_EXPANSION - uint16_t inst_nic = (pdn->ip_addr[3] & 0x000000FF) - 2; - res = sprintf(command_line, - "ifconfig %s%d %s netmask %s broadcast %s up && " - "ip rule add from %s/24 table %d && " - "ip rule add to %s/24 table %d && " - "ip route add default dev %s%d table %d", - UE_NAS_USE_TUN?"oaitun_ue":"oip", - inst_nic + 1, ipv4_addr, netmask, broadcast, - ipv4_addr, 201, - ipv4_addr, 201, - UE_NAS_USE_TUN?"oaitun_ue":"oip", - inst_nic + 1, 201); - inst_pdcp_list[inst_nic] = ueid; -#else - res = sprintf(command_line, - "ifconfig %s%d %s netmask %s broadcast %s up && " - "ip rule add from %s/32 table %d && " - "ip rule add to %s/32 table %d && " - "ip route add default dev %s%d table %d", - UE_NAS_USE_TUN?"oaitun_ue":"oip", - ueid + 1, ipv4_addr, netmask, broadcast, - ipv4_addr, ueid + 201, - ipv4_addr, ueid + 201, - UE_NAS_USE_TUN?"oaitun_ue":"oip", - ueid + 1, ueid + 201); -#endif - } // PDCP_USE_NETLINK - } else { - res = sprintf(command_line, - "ifconfig %s%d %s netmask %s broadcast %s up && " - "ip rule add from %s/32 table %d && " - "ip rule add to %s/32 table %d && " - "ip route add default dev %s%d table %d", - UE_NAS_USE_TUN?"oaitun_ue":"oip", - ueid + 1, ipv4_addr, netmask, broadcast, - ipv4_addr, ueid + 201, - ipv4_addr, ueid + 201, - UE_NAS_USE_TUN?"oaitun_ue":"oip", - ueid + 1, ueid + 201); - } + res = sprintf(command_line, + "ip address add %s/%d broadcast %s dev %s%d && " + "ip link set %s%d up && " + "ip rule add from %s/32 table %d && " + "ip rule add to %s/32 table %d && " + "ip route add default dev %s%d table %d", + ipv4_addr, netmask, broadcast, + UE_NAS_USE_TUN ? "oaitun_ue" : "oip", ueid + 1, + UE_NAS_USE_TUN ? "oaitun_ue" : "oip", ueid + 1, + ipv4_addr, ueid + 10000, + ipv4_addr, ueid + 10000, + UE_NAS_USE_TUN ? "oaitun_ue" : "oip", + ueid + 1, ueid + 10000); if ( res<0 ) { LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string"); diff --git a/openair3/NAS/gNB/network_process_nas.c b/openair3/NAS/gNB/network_process_nas.c new file mode 100644 index 0000000000..ce8897730b --- /dev/null +++ b/openair3/NAS/gNB/network_process_nas.c @@ -0,0 +1,214 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#include + +void SGSabortUE(void *msg, NRUEcontext_t *UE) { +} +void nas_schedule(void) { +} +/* + *Message reception + */ + +void SGSregistrationReq(void *msg, NRUEcontext_t *UE) { +} + +void SGSderegistrationUEReq(void *msg, NRUEcontext_t *UE) { +} + +void SGSidentityResp(void *msg, NRUEcontext_t *UE) { + // use the UE SUPI to load the USIM + IdentityresponseIMSI_t *resp=(IdentityresponseIMSI_t *)msg; + char configName[100]={0}; + char * ptr= stpcpy(configName,"uicc"); + *ptr++=resp->mcc1+'0'; + *ptr++=resp->mcc2+'0'; + *ptr++=resp->mcc3+'0'; + *ptr++=resp->mnc1+'0'; + *ptr++=resp->mnc2+'0'; + if ( resp->mnc3 != 0xF ) + *ptr++=resp->mnc3 +'0'; + int respSize=ntohs(resp->common.len); + int msinByteSize=respSize-sizeof(IdentityresponseIMSI_t); + uint8_t * msin=(uint8_t *) (resp+1); + for(int i=3 ; i> 4) ; + *ptr++=(msin[i] & 0xf) +'0'; + if (digit1 != 0xf) + *ptr++=digit1 +'0'; + } + *ptr=0; + if (UE->uicc == NULL) + // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE + UE->uicc=init_uicc(configName); + //We schedule Authentication request + nas_schedule(); +} + +void SGSauthenticationResp(void *msg, NRUEcontext_t *UE) { + // Let's check the answer + authenticationresponse_t* resp=(authenticationresponse_t*) msg; + uint8_t resStarLocal[16]; + resToresStar(resStarLocal,UE->uicc); + if ( memcmp(resStarLocal, resp->RES, sizeof(resStarLocal)) == 0 ) { + LOG_I(NAS,"UE answer to authentication resquest is correct\n"); + // we will send securityModeCommand + nas_schedule(); + } else { + LOG_E(NAS,"UE authentication response not good\n"); + // To be implemented ? + } +} + +void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE) { + +} + +void SGSregistrationComplete(void *msg, NRUEcontext_t *UE) { +} + +void processNAS(void *msg, NRUEcontext_t *UE) { + SGScommonHeader_t *header=(SGScommonHeader_t *) msg; + + if ( header->sh > 4 ) + SGSabortUE(msg, UE); + else { + switch (header->epd) { + case SGSmobilitymanagementmessages: + LOG_I(NAS,"Received message: %s\n", idStr(message_text_info, header->mt)); + + switch (header->mt) { + case Registrationrequest: + SGSregistrationReq(msg, UE); + break; + + case DeregistrationrequestUEoriginating: + SGSderegistrationUEReq(msg, UE); + break; + + case Authenticationresponse: + SGSauthenticationResp(msg, UE); + break; + + case Identityresponse: + SGSidentityResp(msg, UE); + break; + + case Securitymodecomplete: + SGSsecurityModeComplete(msg, UE); + break; + + case Registrationcomplete: + SGSregistrationComplete(msg, UE); + break; + + default: + SGSabortUE(msg, UE); + } + + break; + + case SGSsessionmanagementmessages: + SGSabortUE(msg, UE); + break; + + default: + SGSabortUE(msg, UE); + } + } +} + +/* + * Messages emission + */ + +int identityRequest(void **msg, NRUEcontext_t *UE) { + myCalloc(req, Identityrequest_t); + req->epd=SGSmobilitymanagementmessages; + req->sh=0; + req->mt=Identityrequest; + req->it=SUCI; + *msg=req; + return sizeof(Identityrequest_t); +} + +int authenticationRequest(void **msg, NRUEcontext_t *UE) { + + myCalloc(req, authenticationrequestHeader_t); + req->epd=SGSmobilitymanagementmessages; + req->sh=0; + req->mt=Authenticationrequest; + // native security context => bit 4 to 0 + // probably from TS 33.501, table A-8.1 + // N-NAS-int-alg (Native NAS integrity) + /* + N-NAS-enc-alg 0x01 + N-NAS-int-alg 0x02 + N-RRC-enc-alg 0x03 + N-RRC-int-alg 0x04 + N-UP-enc-alg 0x05 + N-UP-int-alg 0x06 + */ + req->ngKSI=2; + // TS 33.501, Annex A.7.1: Initial set of security features defined for 5GS. + req->ABBALen=2; + req->ABBA=0; + //rand (TV) + req->ieiRAND=IEI_RAND; + FILE *h=fopen("/dev/random","r"); + + if ( sizeof(req->RAND) != fread(req->RAND,1,sizeof(req->RAND),h) ) + LOG_E(NAS, "can't read /dev/random\n"); + + fclose(h); + memcpy(UE->uicc->rand, req->RAND, sizeof(UE->uicc->rand)); + // challenge/AUTN (TLV) + req->ieiAUTN=IEI_AUTN; + req->AUTNlen=sizeof(req->AUTN); + uicc_milenage_generate( req->AUTN, UE->uicc); + // EAP message (TLV-E) + // not developped + *msg=req; + return sizeof(authenticationrequestHeader_t); +} + +int securityModeCommand(void **msg, NRUEcontext_t *UE) { + *msg=NULL; + myCalloc(req, securityModeCommand_t); + req->epd=SGSmobilitymanagementmessages; + req->sh=0; + req->mt=Securitymodecommand; + + // integrity algo from 5G-IA0 (null algo) to 5G-IA7 in first 4 bits + unsigned int ia=0; + // cyphering algo from 5G-EA0 (null algo) to 5G-IA7 in MSB 4 bits + unsigned int ea=0; + // trace from commercial: 5G-IA0 (0) 128-5G-IA2 (2) + req->selectedNASsecurityalgorithms= ea<<4 | ia; + + // KSI: N-NAS-int-alg 0x02 + req->ngKSI=2; + + *msg=req; + return 0; +} diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c index 70446eea5f..924f28c87f 100644 --- a/openair3/NGAP/ngap_gNB.c +++ b/openair3/NGAP/ngap_gNB.c @@ -61,9 +61,6 @@ #include "assertions.h" #include "conversions.h" -#if defined(TEST_S1C_AMF) - #include "oaisim_amf_test_s1c.h" -#endif ngap_gNB_config_t ngap_config; @@ -98,7 +95,6 @@ static void ngap_gNB_register_amf(ngap_gNB_instance_t *instance_p, MessageDef *message_p = NULL; sctp_new_association_req_t *sctp_new_association_req_p = NULL; ngap_gNB_amf_data_t *ngap_amf_data_p = NULL; - struct ngap_gNB_amf_data_s *amf = NULL; DevAssert(instance_p != NULL); DevAssert(amf_ip_address != NULL); message_p = itti_alloc_new_message(TASK_NGAP, SCTP_NEW_ASSOCIATION_REQ); @@ -114,50 +110,29 @@ static void ngap_gNB_register_amf(ngap_gNB_instance_t *instance_p, local_ip_addr, sizeof(*local_ip_addr)); NGAP_INFO("[gNB %d] check the amf registration state\n",instance_p->instance); - amf = NULL; - if ( amf == NULL ) { - /* Create new AMF descriptor */ - ngap_amf_data_p = calloc(1, sizeof(*ngap_amf_data_p)); - DevAssert(ngap_amf_data_p != NULL); - ngap_amf_data_p->cnx_id = ngap_gNB_fetch_add_global_cnx_id(); - sctp_new_association_req_p->ulp_cnx_id = ngap_amf_data_p->cnx_id; - ngap_amf_data_p->assoc_id = -1; - ngap_amf_data_p->broadcast_plmn_num = broadcast_plmn_num; - memcpy(&ngap_amf_data_p->amf_s1_ip, - amf_ip_address, - sizeof(*amf_ip_address)); - for (int i = 0; i < broadcast_plmn_num; ++i) - ngap_amf_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; + /* Create new AMF descriptor */ + ngap_amf_data_p = calloc(1, sizeof(*ngap_amf_data_p)); + DevAssert(ngap_amf_data_p != NULL); + ngap_amf_data_p->cnx_id = ngap_gNB_fetch_add_global_cnx_id(); + sctp_new_association_req_p->ulp_cnx_id = ngap_amf_data_p->cnx_id; + ngap_amf_data_p->assoc_id = -1; + ngap_amf_data_p->broadcast_plmn_num = broadcast_plmn_num; + memcpy(&ngap_amf_data_p->amf_s1_ip, + amf_ip_address, + sizeof(*amf_ip_address)); + for (int i = 0; i < broadcast_plmn_num; ++i) + ngap_amf_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; - ngap_amf_data_p->ngap_gNB_instance = instance_p; - STAILQ_INIT(&ngap_amf_data_p->served_guami); - /* Insert the new descriptor in list of known AMF - * but not yet associated. - */ - RB_INSERT(ngap_amf_map, &instance_p->ngap_amf_head, ngap_amf_data_p); - ngap_amf_data_p->state = NGAP_GNB_STATE_WAITING; - instance_p->ngap_amf_nb ++; - instance_p->ngap_amf_pending_nb ++; - } else if (amf->state == NGAP_GNB_STATE_WAITING) { - instance_p->ngap_amf_pending_nb ++; - sctp_new_association_req_p->ulp_cnx_id = amf->cnx_id; - NGAP_INFO("[gNB %d] AMF already registered, retrive the data (state %d, cnx %d, amf_nb %d, amf_pending_nb %d)\n", - instance_p->instance, - amf->state, amf->cnx_id, - instance_p->ngap_amf_nb, instance_p->ngap_amf_pending_nb); - /*ngap_amf_data_p->cnx_id = amf->cnx_id; - sctp_new_association_req_p->ulp_cnx_id = amf->cnx_id; - - ngap_amf_data_p->assoc_id = -1; - ngap_amf_data_p->ngap_gNB_instance = instance_p; - */ - } else { - NGAP_WARN("[gNB %d] AMF already registered but not in the waiting state, retrive the data (state %d, cnx %d, amf_nb %d, amf_pending_nb %d)\n", - instance_p->instance, - amf->state, amf->cnx_id, - instance_p->ngap_amf_nb, instance_p->ngap_amf_pending_nb); - } + ngap_amf_data_p->ngap_gNB_instance = instance_p; + STAILQ_INIT(&ngap_amf_data_p->served_guami); + /* Insert the new descriptor in list of known AMF + * but not yet associated. + */ + RB_INSERT(ngap_amf_map, &instance_p->ngap_amf_head, ngap_amf_data_p); + ngap_amf_data_p->state = NGAP_GNB_STATE_WAITING; + instance_p->ngap_amf_nb ++; + instance_p->ngap_amf_pending_nb ++; itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); } @@ -280,13 +255,10 @@ static void ngap_gNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { int result; DevAssert(sctp_data_ind != NULL); -#if defined(TEST_S1C_AMF) - amf_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream, - sctp_data_ind->buffer, sctp_data_ind->buffer_length); -#else + ngap_gNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream, sctp_data_ind->buffer, sctp_data_ind->buffer_length); -#endif + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 10b5baf31c..197cf88a52 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -55,276 +55,276 @@ int ngap_gNB_handle_nas_first_req( instance_t instance, ngap_nas_first_req_t *ngap_nas_first_req_p) //------------------------------------------------------------------------------ { - ngap_gNB_instance_t *instance_p = NULL; - struct ngap_gNB_amf_data_s *amf_desc_p = NULL; - struct ngap_gNB_ue_context_s *ue_desc_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_InitialUEMessage_t *out; - NGAP_InitialUEMessage_IEs_t *ie; - NGAP_UserLocationInformationNR_t *userinfo_nr_p = NULL; - uint8_t *buffer = NULL; - uint32_t length = 0; - DevAssert(ngap_nas_first_req_p != NULL); - /* Retrieve the NGAP gNB instance associated with Mod_id */ - instance_p = ngap_gNB_get_instance(instance); - DevAssert(instance_p != NULL); - memset(&pdu, 0, sizeof(pdu)); - pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t)); - pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_InitialUEMessage; - pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; - pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_InitialUEMessage; - out = &pdu.choice.initiatingMessage->value.choice.InitialUEMessage; + ngap_gNB_instance_t *instance_p = NULL; + struct ngap_gNB_amf_data_s *amf_desc_p = NULL; + struct ngap_gNB_ue_context_s *ue_desc_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_InitialUEMessage_t *out; + NGAP_InitialUEMessage_IEs_t *ie; + NGAP_UserLocationInformationNR_t *userinfo_nr_p = NULL; + uint8_t *buffer = NULL; + uint32_t length = 0; + DevAssert(ngap_nas_first_req_p != NULL); + /* Retrieve the NGAP gNB instance associated with Mod_id */ + instance_p = ngap_gNB_get_instance(instance); + DevAssert(instance_p != NULL); + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_InitialUEMessage; + pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_InitialUEMessage; + out = &pdu.choice.initiatingMessage->value.choice.InitialUEMessage; - /* Select the AMF corresponding to the provided GUAMI. */ + /* Select the AMF corresponding to the provided GUAMI. */ + //TODO have not be test. it's should be test + if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_guami) { + amf_desc_p = ngap_gNB_nnsf_select_amf_by_guami( + instance_p, + ngap_nas_first_req_p->establishment_cause, + ngap_nas_first_req_p->ue_identity.guami); + + if (amf_desc_p) { + NGAP_INFO("[gNB %d] Chose AMF '%s' (assoc_id %d) through GUAMI MCC %d MNC %d AMFRI %d AMFSI %d AMFPT %d\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id, + ngap_nas_first_req_p->ue_identity.guami.mcc, + ngap_nas_first_req_p->ue_identity.guami.mnc, + ngap_nas_first_req_p->ue_identity.guami.amf_region_id, + ngap_nas_first_req_p->ue_identity.guami.amf_set_id, + ngap_nas_first_req_p->ue_identity.guami.amf_pointer); + } + } + + if (amf_desc_p == NULL) { + /* Select the AMF corresponding to the provided s-TMSI. */ //TODO have not be test. it's should be test - if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_guami) { - amf_desc_p = ngap_gNB_nnsf_select_amf_by_guami( + if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) { + amf_desc_p = ngap_gNB_nnsf_select_amf_by_amf_setid( instance_p, ngap_nas_first_req_p->establishment_cause, - ngap_nas_first_req_p->ue_identity.guami); + ngap_nas_first_req_p->selected_plmn_identity, + ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id); if (amf_desc_p) { - NGAP_INFO("[gNB %d] Chose AMF '%s' (assoc_id %d) through GUAMI MCC %d MNC %d AMFRI %d AMFSI %d AMFPT %d\n", - instance, - amf_desc_p->amf_name, - amf_desc_p->assoc_id, - ngap_nas_first_req_p->ue_identity.guami.mcc, - ngap_nas_first_req_p->ue_identity.guami.mnc, - ngap_nas_first_req_p->ue_identity.guami.amf_region_id, - ngap_nas_first_req_p->ue_identity.guami.amf_set_id, - ngap_nas_first_req_p->ue_identity.guami.amf_pointer); - } - } - - if (amf_desc_p == NULL) { - /* Select the AMF corresponding to the provided s-TMSI. */ - //TODO have not be test. it's should be test - if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) { - amf_desc_p = ngap_gNB_nnsf_select_amf_by_amf_setid( - instance_p, - ngap_nas_first_req_p->establishment_cause, - ngap_nas_first_req_p->selected_plmn_identity, - ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id); - - if (amf_desc_p) { - NGAP_INFO("[gNB %d] Chose AMF '%s' (assoc_id %d) through S-TMSI AMFSI %d and selected PLMN Identity index %d MCC %d MNC %d\n", - instance, - amf_desc_p->amf_name, - amf_desc_p->assoc_id, - ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id, - ngap_nas_first_req_p->selected_plmn_identity, - instance_p->mcc[ngap_nas_first_req_p->selected_plmn_identity], - instance_p->mnc[ngap_nas_first_req_p->selected_plmn_identity]); - } - } - } - - if (amf_desc_p == NULL) { - /* Select AMF based on the selected PLMN identity, received through RRC - * Connection Setup Complete */ - //TODO have not be test. it's should be test - amf_desc_p = ngap_gNB_nnsf_select_amf_by_plmn_id( - instance_p, - ngap_nas_first_req_p->establishment_cause, - ngap_nas_first_req_p->selected_plmn_identity); - - if (amf_desc_p) { - NGAP_INFO("[gNB %d] Chose AMF '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", + NGAP_INFO("[gNB %d] Chose AMF '%s' (assoc_id %d) through S-TMSI AMFSI %d and selected PLMN Identity index %d MCC %d MNC %d\n", instance, amf_desc_p->amf_name, amf_desc_p->assoc_id, + ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id, ngap_nas_first_req_p->selected_plmn_identity, instance_p->mcc[ngap_nas_first_req_p->selected_plmn_identity], instance_p->mnc[ngap_nas_first_req_p->selected_plmn_identity]); } } + } - if (amf_desc_p == NULL) { - /* - * If no AMF corresponds to the GUAMI, the s-TMSI, or the selected PLMN - * identity, selects the AMF with the highest capacity. - */ - //TODO have not be test. it's should be test - amf_desc_p = ngap_gNB_nnsf_select_amf( - instance_p, - ngap_nas_first_req_p->establishment_cause); + if (amf_desc_p == NULL) { + /* Select AMF based on the selected PLMN identity, received through RRC + * Connection Setup Complete */ + //TODO have not be test. it's should be test + amf_desc_p = ngap_gNB_nnsf_select_amf_by_plmn_id( + instance_p, + ngap_nas_first_req_p->establishment_cause, + ngap_nas_first_req_p->selected_plmn_identity); - if (amf_desc_p) { - NGAP_INFO("[gNB %d] Chose AMF '%s' (assoc_id %d) through highest relative capacity\n", - instance, - amf_desc_p->amf_name, - amf_desc_p->assoc_id); - } + if (amf_desc_p) { + NGAP_INFO("[gNB %d] Chose AMF '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id, + ngap_nas_first_req_p->selected_plmn_identity, + instance_p->mcc[ngap_nas_first_req_p->selected_plmn_identity], + instance_p->mnc[ngap_nas_first_req_p->selected_plmn_identity]); } + } - if (amf_desc_p == NULL) { - /* - * In case gNB has no AMF associated, the gNB should inform RRC and discard - * this request. - */ - NGAP_WARN("No AMF is associated to the gNB\n"); - // TODO: Inform RRC - return -1; - } - - /* The gNB should allocate a unique gNB UE NGAP ID for this UE. The value - * will be used for the duration of the connectivity. + if (amf_desc_p == NULL) { + /* + * If no AMF corresponds to the GUAMI, the s-TMSI, or the selected PLMN + * identity, selects the AMF with the highest capacity. */ - ue_desc_p = ngap_gNB_allocate_new_UE_context(); - DevAssert(ue_desc_p != NULL); - /* Keep a reference to the selected AMF */ - ue_desc_p->amf_ref = amf_desc_p; - ue_desc_p->ue_initial_id = ngap_nas_first_req_p->ue_initial_id; - ue_desc_p->gNB_instance = instance_p; - ue_desc_p->selected_plmn_identity = ngap_nas_first_req_p->selected_plmn_identity; + //TODO have not be test. it's should be test + amf_desc_p = ngap_gNB_nnsf_select_amf( + instance_p, + ngap_nas_first_req_p->establishment_cause); - do { - struct ngap_gNB_ue_context_s *collision_p; - /* Peek a random value for the gNB_ue_ngap_id */ - ue_desc_p->gNB_ue_ngap_id = (random() + random()) & 0xffffffff; + if (amf_desc_p) { + NGAP_INFO("[gNB %d] Chose AMF '%s' (assoc_id %d) through highest relative capacity\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id); + } + } - if ((collision_p = RB_INSERT(ngap_ue_map, &instance_p->ngap_ue_head, ue_desc_p)) - == NULL) { - NGAP_DEBUG("Found usable gNB_ue_ngap_id: 0x%08x %u(10)\n", - ue_desc_p->gNB_ue_ngap_id, - ue_desc_p->gNB_ue_ngap_id); - /* Break the loop as the id is not already used by another UE */ - break; - } - } while(1); + if (amf_desc_p == NULL) { + /* + * In case gNB has no AMF associated, the gNB should inform RRC and discard + * this request. + */ + NGAP_WARN("No AMF is associated to the gNB\n"); + // TODO: Inform RRC + return -1; + } - /* mandatory */ - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = ue_desc_p->gNB_ue_ngap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_NAS_PDU; + /* The gNB should allocate a unique gNB UE NGAP ID for this UE. The value + * will be used for the duration of the connectivity. + */ + ue_desc_p = ngap_gNB_allocate_new_UE_context(); + DevAssert(ue_desc_p != NULL); + /* Keep a reference to the selected AMF */ + ue_desc_p->amf_ref = amf_desc_p; + ue_desc_p->ue_initial_id = ngap_nas_first_req_p->ue_initial_id; + ue_desc_p->gNB_instance = instance_p; + ue_desc_p->selected_plmn_identity = ngap_nas_first_req_p->selected_plmn_identity; + + do { + struct ngap_gNB_ue_context_s *collision_p; + /* Peek a random value for the gNB_ue_ngap_id */ + ue_desc_p->gNB_ue_ngap_id = (random() + random()) & 0xffffffff; + + if ((collision_p = RB_INSERT(ngap_ue_map, &instance_p->ngap_ue_head, ue_desc_p)) + == NULL) { + NGAP_DEBUG("Found usable gNB_ue_ngap_id: 0x%08x %u(10)\n", + ue_desc_p->gNB_ue_ngap_id, + ue_desc_p->gNB_ue_ngap_id); + /* Break the loop as the id is not already used by another UE */ + break; + } + } while(1); + + /* mandatory */ + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_desc_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_NAS_PDU; #if 1 - ie->value.choice.NAS_PDU.buf = ngap_nas_first_req_p->nas_pdu.buffer; + ie->value.choice.NAS_PDU.buf = ngap_nas_first_req_p->nas_pdu.buffer; #else - ie->value.choice.NAS_PDU.buf = malloc(ngap_nas_first_req_p->nas_pdu.length); - memcpy(ie->value.choice.NAS_PDU.buf, - ngap_nas_first_req_p->nas_pdu.buffer, - ngap_nas_first_req_p->nas_pdu.length); + ie->value.choice.NAS_PDU.buf = malloc(ngap_nas_first_req_p->nas_pdu.length); + memcpy(ie->value.choice.NAS_PDU.buf, + ngap_nas_first_req_p->nas_pdu.buffer, + ngap_nas_first_req_p->nas_pdu.length); #endif - ie->value.choice.NAS_PDU.size = ngap_nas_first_req_p->nas_pdu.length; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* mandatory */ - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_UserLocationInformation; + ie->value.choice.NAS_PDU.size = ngap_nas_first_req_p->nas_pdu.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_UserLocationInformation; - ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; + ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; - ie->value.choice.UserLocationInformation.choice.userLocationInformationNR = - CALLOC(1, sizeof(*ie->value.choice.UserLocationInformation.choice.userLocationInformationNR)); - userinfo_nr_p = ie->value.choice.UserLocationInformation.choice.userLocationInformationNR; + ie->value.choice.UserLocationInformation.choice.userLocationInformationNR = + CALLOC(1, sizeof(*ie->value.choice.UserLocationInformation.choice.userLocationInformationNR)); + userinfo_nr_p = ie->value.choice.UserLocationInformation.choice.userLocationInformationNR; - /* Set nRCellIdentity. default userLocationInformationNR */ - MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id, - 0, // Cell ID - &userinfo_nr_p->nR_CGI.nRCellIdentity); - MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], + /* Set nRCellIdentity. default userLocationInformationNR */ + MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id, + 0, // Cell ID + &userinfo_nr_p->nR_CGI.nRCellIdentity); + MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], + &userinfo_nr_p->nR_CGI.pLMNIdentity); + + /* Set TAI */ + INT24_TO_OCTET_STRING(instance_p->tac, &userinfo_nr_p->tAI.tAC); + MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity], instance_p->mnc[ue_desc_p->selected_plmn_identity], instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], - &userinfo_nr_p->nR_CGI.pLMNIdentity); + &userinfo_nr_p->tAI.pLMNIdentity); - /* Set TAI */ - INT24_TO_OCTET_STRING(instance_p->tac, &userinfo_nr_p->tAI.tAC); - MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity], - instance_p->mnc[ue_desc_p->selected_plmn_identity], - instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], - &userinfo_nr_p->tAI.pLMNIdentity); - - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* Set the establishment cause according to those provided by RRC */ - DevCheck(ngap_nas_first_req_p->establishment_cause < NGAP_RRC_CAUSE_LAST, - ngap_nas_first_req_p->establishment_cause, NGAP_RRC_CAUSE_LAST, 0); - - /* mandatory */ + /* Set the establishment cause according to those provided by RRC */ + DevCheck(ngap_nas_first_req_p->establishment_cause < NGAP_RRC_CAUSE_LAST, + ngap_nas_first_req_p->establishment_cause, NGAP_RRC_CAUSE_LAST, 0); + + /* mandatory */ + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RRCEstablishmentCause; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RRCEstablishmentCause; + ie->value.choice.RRCEstablishmentCause = ngap_nas_first_req_p->establishment_cause; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) { + NGAP_DEBUG("FIVEG_S_TMSI_PRESENT\n"); ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RRCEstablishmentCause; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RRCEstablishmentCause; - ie->value.choice.RRCEstablishmentCause = ngap_nas_first_req_p->establishment_cause; + ie->id = NGAP_ProtocolIE_ID_id_FiveG_S_TMSI; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_FiveG_S_TMSI; + AMF_SETID_TO_BIT_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id, + &ie->value.choice.FiveG_S_TMSI.aMFSetID); + AMF_SETID_TO_BIT_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.amf_pointer, + &ie->value.choice.FiveG_S_TMSI.aMFPointer); + M_TMSI_TO_OCTET_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.m_tmsi, + &ie->value.choice.FiveG_S_TMSI.fiveG_TMSI); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* optional */ - if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) { - NGAP_DEBUG("FIVEG_S_TMSI_PRESENT\n"); - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_FiveG_S_TMSI; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_FiveG_S_TMSI; - AMF_SETID_TO_BIT_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id, - &ie->value.choice.FiveG_S_TMSI.aMFSetID); - AMF_SETID_TO_BIT_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.amf_pointer, - &ie->value.choice.FiveG_S_TMSI.aMFPointer); - M_TMSI_TO_OCTET_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.m_tmsi, - &ie->value.choice.FiveG_S_TMSI.fiveG_TMSI); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + } - /* optional */ - ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_UEContextRequest; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_UEContextRequest; - ie->value.choice.UEContextRequest = NGAP_UEContextRequest_requested; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* optional */ + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_UEContextRequest; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_UEContextRequest; + ie->value.choice.UEContextRequest = NGAP_UEContextRequest_requested; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { - /* Failed to encode message */ - DevMessage("Failed to encode initial UE message\n"); - } + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + /* Failed to encode message */ + DevMessage("Failed to encode initial UE message\n"); + } - /* Update the current NGAP UE state */ - ue_desc_p->ue_state = NGAP_UE_WAITING_CSR; - /* Assign a stream for this UE : - * From 3GPP 38.412 7)Transport layers: - * Within the SCTP association established between one AMF and gNB pair: - * - a single pair of stream identifiers shall be reserved for the sole use - * of NGAP elementary procedures that utilize non UE-associated signalling. - * - At least one pair of stream identifiers shall be reserved for the sole use - * of NGAP elementary procedures that utilize UE-associated signallings. - * However a few pairs (i.e. more than one) should be reserved. - * - A single UE-associated signalling shall use one SCTP stream and - * the stream should not be changed during the communication of the - * UE-associated signalling. - */ - amf_desc_p->nextstream = (amf_desc_p->nextstream + 1) % amf_desc_p->out_streams; + /* Update the current NGAP UE state */ + ue_desc_p->ue_state = NGAP_UE_WAITING_CSR; + /* Assign a stream for this UE : + * From 3GPP 38.412 7)Transport layers: + * Within the SCTP association established between one AMF and gNB pair: + * - a single pair of stream identifiers shall be reserved for the sole use + * of NGAP elementary procedures that utilize non UE-associated signalling. + * - At least one pair of stream identifiers shall be reserved for the sole use + * of NGAP elementary procedures that utilize UE-associated signallings. + * However a few pairs (i.e. more than one) should be reserved. + * - A single UE-associated signalling shall use one SCTP stream and + * the stream should not be changed during the communication of the + * UE-associated signalling. + */ + amf_desc_p->nextstream = (amf_desc_p->nextstream + 1) % amf_desc_p->out_streams; - if ((amf_desc_p->nextstream == 0) && (amf_desc_p->out_streams > 1)) { - amf_desc_p->nextstream += 1; - } + if ((amf_desc_p->nextstream == 0) && (amf_desc_p->out_streams > 1)) { + amf_desc_p->nextstream += 1; + } - ue_desc_p->tx_stream = amf_desc_p->nextstream; - MSC_LOG_TX_MESSAGE( - MSC_NGAP_GNB, - MSC_NGAP_AMF, - (const char *)NULL, - 0, - MSC_AS_TIME_FMT" initialUEMessage initiatingMessage gNB_ue_ngap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - ue_desc_p->gNB_ue_ngap_id); - /* Send encoded message over sctp */ - ngap_gNB_itti_send_sctp_data_req(instance_p->instance, amf_desc_p->assoc_id, - buffer, length, ue_desc_p->tx_stream); + ue_desc_p->tx_stream = amf_desc_p->nextstream; + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)NULL, + 0, + MSC_AS_TIME_FMT" initialUEMessage initiatingMessage gNB_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_desc_p->gNB_ue_ngap_id); + /* Send encoded message over sctp */ + ngap_gNB_itti_send_sctp_data_req(instance_p->instance, amf_desc_p->assoc_id, + buffer, length, ue_desc_p->tx_stream); - return 0; + return 0; } //------------------------------------------------------------------------------ @@ -334,217 +334,217 @@ int ngap_gNB_handle_nas_downlink(uint32_t assoc_id, //------------------------------------------------------------------------------ { - ngap_gNB_amf_data_t *amf_desc_p = NULL; - ngap_gNB_ue_context_t *ue_desc_p = NULL; - ngap_gNB_instance_t *ngap_gNB_instance = NULL; - NGAP_DownlinkNASTransport_t *container; - NGAP_DownlinkNASTransport_IEs_t *ie; - NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; - uint64_t amf_ue_ngap_id; - DevAssert(pdu != NULL); + ngap_gNB_amf_data_t *amf_desc_p = NULL; + ngap_gNB_ue_context_t *ue_desc_p = NULL; + ngap_gNB_instance_t *ngap_gNB_instance = NULL; + NGAP_DownlinkNASTransport_t *container; + NGAP_DownlinkNASTransport_IEs_t *ie; + NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; + uint64_t amf_ue_ngap_id; + DevAssert(pdu != NULL); - /* UE-related procedure -> stream != 0 */ - if (stream == 0) { - NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream == 0\n", - assoc_id); - return -1; - } + /* UE-related procedure -> stream != 0 */ + if (stream == 0) { + NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream == 0\n", + assoc_id); + return -1; + } - if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { - NGAP_ERROR( - "[SCTP %d] Received NAS downlink message for non existing AMF context\n", - assoc_id); - return -1; - } + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR( + "[SCTP %d] Received NAS downlink message for non existing AMF context\n", + assoc_id); + return -1; + } - ngap_gNB_instance = amf_desc_p->ngap_gNB_instance; - /* Prepare the NGAP message to encode */ - container = &pdu->choice.initiatingMessage->value.choice.DownlinkNASTransport; - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, - NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true); - asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); + ngap_gNB_instance = amf_desc_p->ngap_gNB_instance; + /* Prepare the NGAP message to encode */ + container = &pdu->choice.initiatingMessage->value.choice.DownlinkNASTransport; + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, + NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true); + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, - NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); - gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, + NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); + gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; - if ((ue_desc_p = ngap_gNB_get_ue_context(ngap_gNB_instance, - gnb_ue_ngap_id)) == NULL) { - MSC_LOG_RX_DISCARDED_MESSAGE( - MSC_NGAP_GNB, - MSC_NGAP_AMF, - NULL, - 0, - MSC_AS_TIME_FMT" downlinkNASTransport gNB_ue_ngap_id %u amf_ue_ngap_id %u", - gnb_ue_ngap_id, - amf_ue_ngap_id); - NGAP_ERROR("[SCTP %d] Received NAS downlink message for non existing UE context gNB_UE_NGAP_ID: 0x%lx\n", - assoc_id, - gnb_ue_ngap_id); - return -1; - } - - if (0 == ue_desc_p->rx_stream) { - ue_desc_p->rx_stream = stream; - } else if (stream != ue_desc_p->rx_stream) { - NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream %u, expecting %u\n", - assoc_id, stream, ue_desc_p->rx_stream); - return -1; - } - - /* Is it the first outcome of the AMF for this UE ? If so store the amf - * UE ngap id. - */ - if (ue_desc_p->amf_ue_ngap_id == 0) { - ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id; - } else { - /* We already have a amf ue ngap id check the received is the same */ - if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { - NGAP_ERROR("[SCTP %d] Mismatch in AMF UE NGAP ID (0x%lx != 0x%"PRIx64"\n", - assoc_id, - amf_ue_ngap_id, - (uint64_t)ue_desc_p->amf_ue_ngap_id - ); - return -1; - } - } - - MSC_LOG_RX_MESSAGE( + if ((ue_desc_p = ngap_gNB_get_ue_context(ngap_gNB_instance, + gnb_ue_ngap_id)) == NULL) { + MSC_LOG_RX_DISCARDED_MESSAGE( MSC_NGAP_GNB, MSC_NGAP_AMF, NULL, 0, MSC_AS_TIME_FMT" downlinkNASTransport gNB_ue_ngap_id %u amf_ue_ngap_id %u", - assoc_id, + gnb_ue_ngap_id, amf_ue_ngap_id); + NGAP_ERROR("[SCTP %d] Received NAS downlink message for non existing UE context gNB_UE_NGAP_ID: 0x%lx\n", + assoc_id, + gnb_ue_ngap_id); + return -1; + } - NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, - NGAP_ProtocolIE_ID_id_NAS_PDU, true); - /* Forward the NAS PDU to NR-RRC */ - ngap_gNB_itti_send_nas_downlink_ind(ngap_gNB_instance->instance, - ue_desc_p->ue_initial_id, - ue_desc_p->gNB_ue_ngap_id, - ie->value.choice.NAS_PDU.buf, - ie->value.choice.NAS_PDU.size); + if (0 == ue_desc_p->rx_stream) { + ue_desc_p->rx_stream = stream; + } else if (stream != ue_desc_p->rx_stream) { + NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream %u, expecting %u\n", + assoc_id, stream, ue_desc_p->rx_stream); + return -1; + } - return 0; + /* Is it the first outcome of the AMF for this UE ? If so store the amf + * UE ngap id. + */ + if (ue_desc_p->amf_ue_ngap_id == 0) { + ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id; + } else { + /* We already have a amf ue ngap id check the received is the same */ + if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { + NGAP_ERROR("[SCTP %d] Mismatch in AMF UE NGAP ID (0x%lx != 0x%"PRIx64"\n", + assoc_id, + amf_ue_ngap_id, + (uint64_t)ue_desc_p->amf_ue_ngap_id + ); + return -1; + } + } + + MSC_LOG_RX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + NULL, + 0, + MSC_AS_TIME_FMT" downlinkNASTransport gNB_ue_ngap_id %u amf_ue_ngap_id %u", + assoc_id, + amf_ue_ngap_id); + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, + NGAP_ProtocolIE_ID_id_NAS_PDU, true); + /* Forward the NAS PDU to NR-RRC */ + ngap_gNB_itti_send_nas_downlink_ind(ngap_gNB_instance->instance, + ue_desc_p->ue_initial_id, + ue_desc_p->gNB_ue_ngap_id, + ie->value.choice.NAS_PDU.buf, + ie->value.choice.NAS_PDU.size); + + return 0; } //------------------------------------------------------------------------------ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_p) //------------------------------------------------------------------------------ { - struct ngap_gNB_ue_context_s *ue_context_p; - ngap_gNB_instance_t *ngap_gNB_instance_p; - NGAP_NGAP_PDU_t pdu; - NGAP_UplinkNASTransport_t *out; - NGAP_UplinkNASTransport_IEs_t *ie; - NGAP_UserLocationInformationNR_t *userinfo_nr_p = NULL; - uint8_t *buffer; - uint32_t length; - DevAssert(ngap_uplink_nas_p != NULL); - /* Retrieve the NGAP gNB instance associated with Mod_id */ - ngap_gNB_instance_p = ngap_gNB_get_instance(instance); - DevAssert(ngap_gNB_instance_p != NULL); + struct ngap_gNB_ue_context_s *ue_context_p; + ngap_gNB_instance_t *ngap_gNB_instance_p; + NGAP_NGAP_PDU_t pdu; + NGAP_UplinkNASTransport_t *out; + NGAP_UplinkNASTransport_IEs_t *ie; + NGAP_UserLocationInformationNR_t *userinfo_nr_p = NULL; + uint8_t *buffer; + uint32_t length; + DevAssert(ngap_uplink_nas_p != NULL); + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, ngap_uplink_nas_p->gNB_ue_ngap_id)) == NULL) { - /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ - NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %08x\n", - ngap_uplink_nas_p->gNB_ue_ngap_id); - return -1; - } + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, ngap_uplink_nas_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %08x\n", + ngap_uplink_nas_p->gNB_ue_ngap_id); + return -1; + } - /* Uplink NAS transport can occur either during an ngap connected state - * or during initial attach (for example: NAS authentication). - */ - if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || - ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { - NGAP_WARN("You are attempting to send NAS data over non-connected " - "gNB ue ngap id: %u, current state: %d\n", - ngap_uplink_nas_p->gNB_ue_ngap_id, ue_context_p->ue_state); - return -1; - } + /* Uplink NAS transport can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || + ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN("You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %u, current state: %d\n", + ngap_uplink_nas_p->gNB_ue_ngap_id, ue_context_p->ue_state); + return -1; + } - /* Prepare the NGAP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UplinkNASTransport; - pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; - pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UplinkNASTransport; - out = &pdu.choice.initiatingMessage->value.choice.UplinkNASTransport; - /* mandatory */ - ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_AMF_UE_NGAP_ID; - //ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_NAS_PDU; - ie->value.choice.NAS_PDU.buf = ngap_uplink_nas_p->nas_pdu.buffer; - ie->value.choice.NAS_PDU.size = ngap_uplink_nas_p->nas_pdu.length; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_UserLocationInformation; + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UplinkNASTransport; + pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UplinkNASTransport; + out = &pdu.choice.initiatingMessage->value.choice.UplinkNASTransport; + /* mandatory */ + ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_AMF_UE_NGAP_ID; + //ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_NAS_PDU; + ie->value.choice.NAS_PDU.buf = ngap_uplink_nas_p->nas_pdu.buffer; + ie->value.choice.NAS_PDU.size = ngap_uplink_nas_p->nas_pdu.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_UserLocationInformation; - ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; - userinfo_nr_p = ie->value.choice.UserLocationInformation.choice.userLocationInformationNR; + ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; + userinfo_nr_p = ie->value.choice.UserLocationInformation.choice.userLocationInformationNR; - /* Set nRCellIdentity. default userLocationInformationNR */ - MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id, - 0, // Cell ID - &userinfo_nr_p->nR_CGI.nRCellIdentity); - MCC_MNC_TO_TBCD(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + /* Set nRCellIdentity. default userLocationInformationNR */ + MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id, + 0, // Cell ID + &userinfo_nr_p->nR_CGI.nRCellIdentity); + MCC_MNC_TO_TBCD(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + ngap_gNB_instance_p->mnc[ue_context_p->selected_plmn_identity], + ngap_gNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], + &userinfo_nr_p->nR_CGI.pLMNIdentity); + + /* Set TAI */ + INT24_TO_OCTET_STRING(ngap_gNB_instance_p->tac, &userinfo_nr_p->tAI.tAC); + MCC_MNC_TO_PLMNID(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], ngap_gNB_instance_p->mnc[ue_context_p->selected_plmn_identity], ngap_gNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], - &userinfo_nr_p->nR_CGI.pLMNIdentity); - - /* Set TAI */ - INT24_TO_OCTET_STRING(ngap_gNB_instance_p->tac, &userinfo_nr_p->tAI.tAC); - MCC_MNC_TO_PLMNID(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], - ngap_gNB_instance_p->mnc[ue_context_p->selected_plmn_identity], - ngap_gNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], - &userinfo_nr_p->tAI.pLMNIdentity); + &userinfo_nr_p->tAI.pLMNIdentity); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { - NGAP_ERROR("Failed to encode uplink NAS transport\n"); - /* Encode procedure has failed... */ - return -1; - } + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode uplink NAS transport\n"); + /* Encode procedure has failed... */ + return -1; + } - MSC_LOG_TX_MESSAGE( - MSC_NGAP_GNB, - MSC_NGAP_AMF, - (const char *)NULL, - 0, - MSC_AS_TIME_FMT" uplinkNASTransport initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->gNB_ue_ngap_id, - ue_context_p->amf_ue_ngap_id); - /* UE associated signalling -> use the allocated stream */ - ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, - ue_context_p->amf_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)NULL, + 0, + MSC_AS_TIME_FMT" uplinkNASTransport initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); - return 0; + return 0; } @@ -553,92 +553,92 @@ int ngap_gNB_nas_non_delivery_ind(instance_t instance, ngap_nas_non_delivery_ind_t *ngap_nas_non_delivery_ind) //------------------------------------------------------------------------------ { - struct ngap_gNB_ue_context_s *ue_context_p; - ngap_gNB_instance_t *ngap_gNB_instance_p; - NGAP_NGAP_PDU_t pdu; - NGAP_NASNonDeliveryIndication_t *out; - NGAP_NASNonDeliveryIndication_IEs_t *ie; - uint8_t *buffer; - uint32_t length; - DevAssert(ngap_nas_non_delivery_ind != NULL); - /* Retrieve the NGAP gNB instance associated with Mod_id */ - ngap_gNB_instance_p = ngap_gNB_get_instance(instance); - DevAssert(ngap_gNB_instance_p != NULL); + struct ngap_gNB_ue_context_s *ue_context_p; + ngap_gNB_instance_t *ngap_gNB_instance_p; + NGAP_NGAP_PDU_t pdu; + NGAP_NASNonDeliveryIndication_t *out; + NGAP_NASNonDeliveryIndication_IEs_t *ie; + uint8_t *buffer; + uint32_t length; + DevAssert(ngap_nas_non_delivery_ind != NULL); + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, ngap_nas_non_delivery_ind->gNB_ue_ngap_id)) == NULL) { - /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ - NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %08x\n", - ngap_nas_non_delivery_ind->gNB_ue_ngap_id); - MSC_LOG_EVENT( - MSC_NGAP_GNB, - MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to AMF failed, no context for gNB_ue_ngap_id %08x", - ngap_nas_non_delivery_ind->gNB_ue_ngap_id); - return -1; - } - - /* Prepare the NGAP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_NASNonDeliveryIndication; - pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; - pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_NASNonDeliveryIndication; - out = &pdu.choice.initiatingMessage->value.choice.NASNonDeliveryIndication; - /* mandatory */ - ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_AMF_UE_NGAP_ID; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_NAS_PDU; - ie->value.choice.NAS_PDU.buf = ngap_nas_non_delivery_ind->nas_pdu.buffer; - ie->value.choice.NAS_PDU.size = ngap_nas_non_delivery_ind->nas_pdu.length; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_Cause; - ie->criticality = NGAP_Criticality_ignore; - /* Send a dummy cause */ - ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_Cause; - ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork; - ie->value.choice.Cause.choice.radioNetwork = NGAP_CauseRadioNetwork_radio_connection_with_ue_lost; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { - NGAP_ERROR("Failed to encode NAS NON delivery indication\n"); - /* Encode procedure has failed... */ - MSC_LOG_EVENT( - MSC_NGAP_GNB, - MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to AMF failed (encoding)"); - return -1; - } - - MSC_LOG_TX_MESSAGE( + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, ngap_nas_non_delivery_ind->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %08x\n", + ngap_nas_non_delivery_ind->gNB_ue_ngap_id); + MSC_LOG_EVENT( MSC_NGAP_GNB, - MSC_NGAP_AMF, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" NASNonDeliveryIndication initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %lu", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->gNB_ue_ngap_id, - ue_context_p->amf_ue_ngap_id); - /* UE associated signalling -> use the allocated stream */ - ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, - ue_context_p->amf_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); + MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to AMF failed, no context for gNB_ue_ngap_id %08x", + ngap_nas_non_delivery_ind->gNB_ue_ngap_id); + return -1; + } - return 0; + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_NASNonDeliveryIndication; + pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_NASNonDeliveryIndication; + out = &pdu.choice.initiatingMessage->value.choice.NASNonDeliveryIndication; + /* mandatory */ + ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_NAS_PDU; + ie->value.choice.NAS_PDU.buf = ngap_nas_non_delivery_ind->nas_pdu.buffer; + ie->value.choice.NAS_PDU.size = ngap_nas_non_delivery_ind->nas_pdu.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_Cause; + ie->criticality = NGAP_Criticality_ignore; + /* Send a dummy cause */ + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_Cause; + ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = NGAP_CauseRadioNetwork_radio_connection_with_ue_lost; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode NAS NON delivery indication\n"); + /* Encode procedure has failed... */ + MSC_LOG_EVENT( + MSC_NGAP_GNB, + MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to AMF failed (encoding)"); + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" NASNonDeliveryIndication initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %lu", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + + return 0; } //------------------------------------------------------------------------------ @@ -647,221 +647,221 @@ int ngap_gNB_initial_ctxt_resp( //------------------------------------------------------------------------------ { - ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; - struct ngap_gNB_ue_context_s *ue_context_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_InitialContextSetupResponse_t *out; - NGAP_InitialContextSetupResponseIEs_t *ie; - uint8_t *buffer = NULL; - uint32_t length; - int i; - asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_InitialContextSetupResponse_t *out; + NGAP_InitialContextSetupResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(initial_ctxt_resp_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + initial_ctxt_resp_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", + initial_ctxt_resp_p->gNB_ue_ngap_id); + return -1; + } + + /* Uplink NAS transport can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || + ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN("You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %08x, current state: %d\n", + initial_ctxt_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_InitialContextSetup; + pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_InitialContextSetupResponse; + out = &pdu.choice.successfulOutcome->value.choice.InitialContextSetupResponse; + /* mandatory */ + ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_AMF_UE_NGAP_ID; + //ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = initial_ctxt_resp_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* optional */ + ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtRes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceSetupListCxtRes; + + for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions; i++) { + NGAP_PDUSessionResourceSetupItemCxtRes_t *item; + NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = NULL; + + /* mandatory */ + item = (NGAP_PDUSessionResourceSetupItemCxtRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupItemCxtRes_t)); + + /* pDUSessionID */ + item->pDUSessionID = initial_ctxt_resp_p->pdusessions[i].pdusession_id; + + /* dLQosFlowPerTNLInformation */ + pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t)); + + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; + + GTP_TEID_TO_ASN1(initial_ctxt_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID); + + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(initial_ctxt_resp_p->pdusessions[i].gNB_addr.length); + + memcpy(pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf, + initial_ctxt_resp_p->pdusessions[i].gNB_addr.buffer, + initial_ctxt_resp_p->pdusessions[i].gNB_addr.length); + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size = initial_ctxt_resp_p->pdusessions[i].gNB_addr.length; + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.bits_unused = 0; + + NGAP_DEBUG("initial_ctxt_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n", + item->pDUSessionID, + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[0], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[1], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[2], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[3], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size); + + /* associatedQosFlowList. number of 1? */ + for(int j=0; j < initial_ctxt_resp_p->pdusessions[i].nb_of_qos_flow; j++) { + NGAP_AssociatedQosFlowItem_t *ass_qos_item_p; + ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t)); + + /* qosFlowIdentifier */ + ass_qos_item_p->qosFlowIdentifier = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qci; + + /* qosFlowMappingIndication */ + if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { + ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); + *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; + } + ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p); + } + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); + item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer; + item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); - /* Retrieve the NGAP gNB instance associated with Mod_id */ - ngap_gNB_instance_p = ngap_gNB_get_instance(instance); - DevAssert(initial_ctxt_resp_p != NULL); - DevAssert(ngap_gNB_instance_p != NULL); + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceSetupListCxtRes.list, item); + } - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - initial_ctxt_resp_p->gNB_ue_ngap_id)) == NULL) { - /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ - NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", - initial_ctxt_resp_p->gNB_ue_ngap_id); - return -1; - } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* Uplink NAS transport can occur either during an ngap connected state - * or during initial attach (for example: NAS authentication). - */ - if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || - ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { - NGAP_WARN("You are attempting to send NAS data over non-connected " - "gNB ue ngap id: %08x, current state: %d\n", - initial_ctxt_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); - return -1; - } - - /* Prepare the NGAP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_InitialContextSetup; - pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; - pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_InitialContextSetupResponse; - out = &pdu.choice.successfulOutcome->value.choice.InitialContextSetupResponse; - /* mandatory */ + /* optional */ + if (initial_ctxt_resp_p->nb_of_pdusessions_failed) { ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToSetupListCxtRes; ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_AMF_UE_NGAP_ID; - //ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = initial_ctxt_resp_p->gNB_ue_ngap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* optional */ - ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtRes; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceSetupListCxtRes; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListCxtRes; - for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions; i++) { - NGAP_PDUSessionResourceSetupItemCxtRes_t *item; - NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = NULL; - + for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions_failed; i++) { + NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t *item; + NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = NULL; + /* mandatory */ - item = (NGAP_PDUSessionResourceSetupItemCxtRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupItemCxtRes_t)); - + item = (NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t)); /* pDUSessionID */ - item->pDUSessionID = initial_ctxt_resp_p->pdusessions[i].pdusession_id; + item->pDUSessionID = initial_ctxt_resp_p->pdusessions_failed[i].pdusession_id; - /* dLQosFlowPerTNLInformation */ - pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t)); + /* cause */ + pdusessionUnTransfer_p = (NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t)); + pdusessionUnTransfer_p->cause.present = initial_ctxt_resp_p->pdusessions_failed[i].cause; + switch(pdusessionUnTransfer_p->cause.present) { + case NGAP_Cause_PR_radioNetwork: + pdusessionUnTransfer_p->cause.choice.radioNetwork = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + break; - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; - - GTP_TEID_TO_ASN1(initial_ctxt_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID); + case NGAP_Cause_PR_transport: + pdusessionUnTransfer_p->cause.choice.transport = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + break; - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(initial_ctxt_resp_p->pdusessions[i].gNB_addr.length); + case NGAP_Cause_PR_nas: + pdusessionUnTransfer_p->cause.choice.nas = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + break; - memcpy(pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf, - initial_ctxt_resp_p->pdusessions[i].gNB_addr.buffer, - initial_ctxt_resp_p->pdusessions[i].gNB_addr.length); - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size = initial_ctxt_resp_p->pdusessions[i].gNB_addr.length; - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.bits_unused = 0; + case NGAP_Cause_PR_protocol: + pdusessionUnTransfer_p->cause.choice.protocol = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + break; - NGAP_DEBUG("initial_ctxt_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n", - item->pDUSessionID, - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[0], - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[1], - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[2], - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[3], - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size); + case NGAP_Cause_PR_misc: + pdusessionUnTransfer_p->cause.choice.misc = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + break; - /* associatedQosFlowList. number of 1? */ - for(int j=0; j < initial_ctxt_resp_p->pdusessions[i].nb_of_qos_flow; j++) { - NGAP_AssociatedQosFlowItem_t *ass_qos_item_p; - ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t)); - - /* qosFlowIdentifier */ - ass_qos_item_p->qosFlowIdentifier = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qci; - - /* qosFlowMappingIndication */ - if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { - ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); - *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; - } - ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p); + case NGAP_Cause_PR_NOTHING: + default: + break; } - - memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); - item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer; - item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded; - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); - - ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceSetupListCxtRes.list, item); + NGAP_DEBUG("initial context setup response: failed pdusession ID %ld\n", item->pDUSessionID); + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); + item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer; + item->pDUSessionResourceSetupUnsuccessfulTransfer.size = res.result.encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); + + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceFailedToSetupListCxtRes.list, item); } ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - /* optional */ - if (initial_ctxt_resp_p->nb_of_pdusessions_failed) { - ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToSetupListCxtRes; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListCxtRes; + /* optional */ + if (0) { + ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics =; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions_failed; i++) { - NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t *item; - NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = NULL; - - /* mandatory */ - item = (NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t)); - /* pDUSessionID */ - item->pDUSessionID = initial_ctxt_resp_p->pdusessions_failed[i].pdusession_id; + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode InitialContextSetupResponse\n"); + /* Encode procedure has failed... */ + return -1; + } - /* cause */ - pdusessionUnTransfer_p = (NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t)); - pdusessionUnTransfer_p->cause.present = initial_ctxt_resp_p->pdusessions_failed[i].cause; - switch(pdusessionUnTransfer_p->cause.present) { - case NGAP_Cause_PR_radioNetwork: - pdusessionUnTransfer_p->cause.choice.radioNetwork = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; - break; + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + initial_ctxt_resp_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); - case NGAP_Cause_PR_transport: - pdusessionUnTransfer_p->cause.choice.transport = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_Cause_PR_nas: - pdusessionUnTransfer_p->cause.choice.nas = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_Cause_PR_protocol: - pdusessionUnTransfer_p->cause.choice.protocol = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_Cause_PR_misc: - pdusessionUnTransfer_p->cause.choice.misc = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_Cause_PR_NOTHING: - default: - break; - } - - NGAP_DEBUG("initial context setup response: failed pdusession ID %ld\n", item->pDUSessionID); - - memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); - item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer; - item->pDUSessionResourceSetupUnsuccessfulTransfer.size = res.result.encoded; - - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); - - ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceFailedToSetupListCxtRes.list, item); - } - - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (0) { - ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_CriticalityDiagnostics; - // ie->value.choice.CriticalityDiagnostics =; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { - NGAP_ERROR("Failed to encode InitialContextSetupResponse\n"); - /* Encode procedure has failed... */ - return -1; - } - - MSC_LOG_TX_MESSAGE( - MSC_NGAP_GNB, - MSC_NGAP_AMF, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - initial_ctxt_resp_p->gNB_ue_ngap_id, - ue_context_p->amf_ue_ngap_id); - /* UE associated signalling -> use the allocated stream */ - ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, - ue_context_p->amf_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); - - return 0; + return 0; } //------------------------------------------------------------------------------ @@ -869,89 +869,89 @@ int ngap_gNB_ue_capabilities(instance_t instance, ngap_ue_cap_info_ind_t *ue_cap_info_ind_p) //------------------------------------------------------------------------------ { - ngap_gNB_instance_t *ngap_gNB_instance_p; - struct ngap_gNB_ue_context_s *ue_context_p; - NGAP_NGAP_PDU_t pdu; - NGAP_UERadioCapabilityInfoIndication_t *out; - NGAP_UERadioCapabilityInfoIndicationIEs_t *ie; - uint8_t *buffer; - uint32_t length; - /* Retrieve the NGAP gNB instance associated with Mod_id */ - ngap_gNB_instance_p = ngap_gNB_get_instance(instance); - DevAssert(ue_cap_info_ind_p != NULL); - DevAssert(ngap_gNB_instance_p != NULL); + ngap_gNB_instance_t *ngap_gNB_instance_p; + struct ngap_gNB_ue_context_s *ue_context_p; + NGAP_NGAP_PDU_t pdu; + NGAP_UERadioCapabilityInfoIndication_t *out; + NGAP_UERadioCapabilityInfoIndicationIEs_t *ie; + uint8_t *buffer; + uint32_t length; + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(ue_cap_info_ind_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - ue_cap_info_ind_p->gNB_ue_ngap_id)) == NULL) { - /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ - NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n", - ue_cap_info_ind_p->gNB_ue_ngap_id); - return -1; - } + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + ue_cap_info_ind_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n", + ue_cap_info_ind_p->gNB_ue_ngap_id); + return -1; + } - /* UE radio capabilities message can occur either during an ngap connected state - * or during initial attach (for example: NAS authentication). - */ - if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || - ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { - NGAP_WARN("You are attempting to send NAS data over non-connected " - "gNB ue ngap id: %u, current state: %d\n", - ue_cap_info_ind_p->gNB_ue_ngap_id, ue_context_p->ue_state); - return -1; - } + /* UE radio capabilities message can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || + ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN("You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %u, current state: %d\n", + ue_cap_info_ind_p->gNB_ue_ngap_id, ue_context_p->ue_state); + return -1; + } - /* Prepare the NGAP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication; - pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; - pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UERadioCapabilityInfoIndication; - out = &pdu.choice.initiatingMessage->value.choice.UERadioCapabilityInfoIndication; - /* mandatory */ - ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_AMF_UE_NGAP_ID; - //ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = ue_cap_info_ind_p->gNB_ue_ngap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_UERadioCapability; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_UERadioCapability; - ie->value.choice.UERadioCapability.buf = ue_cap_info_ind_p->ue_radio_cap.buffer; - ie->value.choice.UERadioCapability.size = ue_cap_info_ind_p->ue_radio_cap.length; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* optional */ - //NGAP_UERadioCapabilityForPaging TBD - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { - /* Encode procedure has failed... */ - NGAP_ERROR("Failed to encode UE radio capabilities indication\n"); - return -1; - } + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication; + pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UERadioCapabilityInfoIndication; + out = &pdu.choice.initiatingMessage->value.choice.UERadioCapabilityInfoIndication; + /* mandatory */ + ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_AMF_UE_NGAP_ID; + //ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_cap_info_ind_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_UERadioCapability; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_UERadioCapability; + ie->value.choice.UERadioCapability.buf = ue_cap_info_ind_p->ue_radio_cap.buffer; + ie->value.choice.UERadioCapability.size = ue_cap_info_ind_p->ue_radio_cap.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* optional */ + //NGAP_UERadioCapabilityForPaging TBD + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + /* Encode procedure has failed... */ + NGAP_ERROR("Failed to encode UE radio capabilities indication\n"); + return -1; + } - MSC_LOG_TX_MESSAGE( - MSC_NGAP_GNB, - MSC_NGAP_AMF, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" UECapabilityInfoIndication initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - ue_cap_info_ind_p->gNB_ue_ngap_id, - ue_context_p->amf_ue_ngap_id); - /* UE associated signalling -> use the allocated stream */ - ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, - ue_context_p->amf_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); - return 0; + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" UECapabilityInfoIndication initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_cap_info_ind_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + return 0; } //------------------------------------------------------------------------------ @@ -959,221 +959,221 @@ int ngap_gNB_pdusession_setup_resp(instance_t instance, ngap_pdusession_setup_resp_t *pdusession_setup_resp_p) //------------------------------------------------------------------------------ { - ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; - struct ngap_gNB_ue_context_s *ue_context_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_PDUSessionResourceSetupResponse_t *out; - NGAP_PDUSessionResourceSetupResponseIEs_t *ie; - uint8_t *buffer = NULL; - uint32_t length; - int i; - asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_PDUSessionResourceSetupResponse_t *out; + NGAP_PDUSessionResourceSetupResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; - /* Retrieve the NGAP gNB instance associated with Mod_id */ - ngap_gNB_instance_p = ngap_gNB_get_instance(instance); - DevAssert(pdusession_setup_resp_p != NULL); - DevAssert(ngap_gNB_instance_p != NULL); + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(pdusession_setup_resp_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - pdusession_setup_resp_p->gNB_ue_ngap_id)) == NULL) { - /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ - NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", - pdusession_setup_resp_p->gNB_ue_ngap_id); - return -1; - } + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + pdusession_setup_resp_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", + pdusession_setup_resp_p->gNB_ue_ngap_id); + return -1; + } - /* Uplink NAS transport can occur either during an ngap connected state - * or during initial attach (for example: NAS authentication). - */ - if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || - ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { - NGAP_WARN("You are attempting to send NAS data over non-connected " - "gNB ue ngap id: %08x, current state: %d\n", - pdusession_setup_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); - return -1; - } + /* Uplink NAS transport can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || + ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN("You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %08x, current state: %d\n", + pdusession_setup_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); + return -1; + } - /* Prepare the NGAP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceSetup; - pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; - pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceSetupResponse; - out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceSetupResponse; - /* mandatory */ + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceSetup; + pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceSetupResponse; + out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceSetupResponse; + /* mandatory */ + ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = pdusession_setup_resp_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (pdusession_setup_resp_p->nb_of_pdusessions > 0) { ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSURes; ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_AMF_UE_NGAP_ID; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceSetupListSURes; + + for (i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions; i++) { + NGAP_PDUSessionResourceSetupItemSURes_t *item; + NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = NULL; + + /* mandatory */ + item = (NGAP_PDUSessionResourceSetupItemSURes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupItemSURes_t)); + + /* pDUSessionID */ + item->pDUSessionID = pdusession_setup_resp_p->pdusessions[i].pdusession_id; + + /* dLQosFlowPerTNLInformation */ + pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t)); + + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; + + GTP_TEID_TO_ASN1(pdusession_setup_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID); + + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(pdusession_setup_resp_p->pdusessions[i].gNB_addr.length); + + memcpy(pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf, + pdusession_setup_resp_p->pdusessions[i].gNB_addr.buffer, + pdusession_setup_resp_p->pdusessions[i].gNB_addr.length); + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size = pdusession_setup_resp_p->pdusessions[i].gNB_addr.length; + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.bits_unused = 0; + + NGAP_DEBUG("pdusession_setup_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n", + item->pDUSessionID, + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[0], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[1], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[2], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[3], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size); + + /* associatedQosFlowList. number of 1? */ + for(int j=0; j < pdusession_setup_resp_p->pdusessions[i].nb_of_qos_flow; j++) { + NGAP_AssociatedQosFlowItem_t *ass_qos_item_p; + ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t)); + + /* qosFlowIdentifier */ + ass_qos_item_p->qosFlowIdentifier = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qci; + + /* qosFlowMappingIndication */ + if(pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { + ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); + *ass_qos_item_p->qosFlowMappingIndication = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; + } + ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p); + } + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); + item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer; + item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); + + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceSetupListSURes.list, item); + } ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ + } + + /* optional */ + if (pdusession_setup_resp_p->nb_of_pdusessions_failed > 0) { ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToSetupListSURes; ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = pdusession_setup_resp_p->gNB_ue_ngap_id; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListSURes; + + for (i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions_failed; i++) { + NGAP_PDUSessionResourceFailedToSetupItemSURes_t *item; + NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = NULL; + + /* mandatory */ + item = (NGAP_PDUSessionResourceFailedToSetupItemSURes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToSetupItemSURes_t)); + /* pDUSessionID */ + item->pDUSessionID = pdusession_setup_resp_p->pdusessions_failed[i].pdusession_id; + + /* cause */ + pdusessionUnTransfer_p = (NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t)); + pdusessionUnTransfer_p->cause.present = pdusession_setup_resp_p->pdusessions_failed[i].cause; + switch(pdusessionUnTransfer_p->cause.present) { + case NGAP_Cause_PR_radioNetwork: + pdusessionUnTransfer_p->cause.choice.radioNetwork = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_transport: + pdusessionUnTransfer_p->cause.choice.transport = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_nas: + pdusessionUnTransfer_p->cause.choice.nas = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_protocol: + pdusessionUnTransfer_p->cause.choice.protocol = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_misc: + pdusessionUnTransfer_p->cause.choice.misc = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_NOTHING: + default: + break; + } + + NGAP_DEBUG("pdusession setup response: failed pdusession ID %ld\n", item->pDUSessionID); + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); + item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer; + item->pDUSessionResourceSetupUnsuccessfulTransfer.size = res.result.encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); + + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceFailedToSetupListSURes.list, item); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - /* optional */ - if (pdusession_setup_resp_p->nb_of_pdusessions > 0) { - ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSURes; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceSetupListSURes; - - for (i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions; i++) { - NGAP_PDUSessionResourceSetupItemSURes_t *item; - NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = NULL; - - /* mandatory */ - item = (NGAP_PDUSessionResourceSetupItemSURes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupItemSURes_t)); - - /* pDUSessionID */ - item->pDUSessionID = pdusession_setup_resp_p->pdusessions[i].pdusession_id; - - /* dLQosFlowPerTNLInformation */ - pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t)); - - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; - - GTP_TEID_TO_ASN1(pdusession_setup_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID); - - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(pdusession_setup_resp_p->pdusessions[i].gNB_addr.length); - - memcpy(pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf, - pdusession_setup_resp_p->pdusessions[i].gNB_addr.buffer, - pdusession_setup_resp_p->pdusessions[i].gNB_addr.length); - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size = pdusession_setup_resp_p->pdusessions[i].gNB_addr.length; - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.bits_unused = 0; - - NGAP_DEBUG("pdusession_setup_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n", - item->pDUSessionID, - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[0], - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[1], - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[2], - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[3], - pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size); - - /* associatedQosFlowList. number of 1? */ - for(int j=0; j < pdusession_setup_resp_p->pdusessions[i].nb_of_qos_flow; j++) { - NGAP_AssociatedQosFlowItem_t *ass_qos_item_p; - ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t)); - - /* qosFlowIdentifier */ - ass_qos_item_p->qosFlowIdentifier = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qci; - - /* qosFlowMappingIndication */ - if(pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { - ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); - *ass_qos_item_p->qosFlowMappingIndication = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; - } - ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p); - } - - memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); - item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer; - item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded; - - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); - - ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceSetupListSURes.list, item); - } - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (pdusession_setup_resp_p->nb_of_pdusessions_failed > 0) { - ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToSetupListSURes; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListSURes; - - for (i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions_failed; i++) { - NGAP_PDUSessionResourceFailedToSetupItemSURes_t *item; - NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = NULL; - - /* mandatory */ - item = (NGAP_PDUSessionResourceFailedToSetupItemSURes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToSetupItemSURes_t)); - /* pDUSessionID */ - item->pDUSessionID = pdusession_setup_resp_p->pdusessions_failed[i].pdusession_id; - - /* cause */ - pdusessionUnTransfer_p = (NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t)); - pdusessionUnTransfer_p->cause.present = pdusession_setup_resp_p->pdusessions_failed[i].cause; - switch(pdusessionUnTransfer_p->cause.present) { - case NGAP_Cause_PR_radioNetwork: - pdusessionUnTransfer_p->cause.choice.radioNetwork = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_Cause_PR_transport: - pdusessionUnTransfer_p->cause.choice.transport = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_Cause_PR_nas: - pdusessionUnTransfer_p->cause.choice.nas = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_Cause_PR_protocol: - pdusessionUnTransfer_p->cause.choice.protocol = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_Cause_PR_misc: - pdusessionUnTransfer_p->cause.choice.misc = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; - break; - - case NGAP_Cause_PR_NOTHING: - default: - break; - } - - NGAP_DEBUG("pdusession setup response: failed pdusession ID %ld\n", item->pDUSessionID); - - memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); - item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer; - item->pDUSessionResourceSetupUnsuccessfulTransfer.size = res.result.encoded; - - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); - - ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceFailedToSetupListSURes.list, item); - } - - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (0) { - ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_CriticalityDiagnostics; - // ie->value.choice.CriticalityDiagnostics = ; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ + if (0) { + ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { - NGAP_ERROR("Failed to encode uplink transport\n"); - /* Encode procedure has failed... */ - return -1; - } + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode uplink transport\n"); + /* Encode procedure has failed... */ + return -1; + } - MSC_LOG_TX_MESSAGE( - MSC_NGAP_GNB, - MSC_NGAP_AMF, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" PduSession Setup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - pdusession_setup_resp_p->gNB_ue_ngap_id, - ue_context_p->amf_ue_ngap_id); - /* UE associated signalling -> use the allocated stream */ - ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, - ue_context_p->amf_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); - return 0; + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" PduSession Setup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + pdusession_setup_resp_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + return 0; } //------------------------------------------------------------------------------ @@ -1181,265 +1181,265 @@ int ngap_gNB_pdusession_modify_resp(instance_t instance, ngap_pdusession_modify_resp_t *pdusession_modify_resp_p) //------------------------------------------------------------------------------ { - ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; - struct ngap_gNB_ue_context_s *ue_context_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_PDUSessionResourceModifyResponse_t *out; - NGAP_PDUSessionResourceModifyResponseIEs_t *ie; - uint8_t *buffer = NULL; - uint32_t length; - int i; - asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_PDUSessionResourceModifyResponse_t *out; + NGAP_PDUSessionResourceModifyResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(pdusession_modify_resp_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + pdusession_modify_resp_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", + pdusession_modify_resp_p->gNB_ue_ngap_id); + return -1; + } + + /* Uplink NAS transport can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || + ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN("You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %08x, current state: %d\n", + pdusession_modify_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceModify; + pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceModifyResponse; + out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceModifyResponse; + /* mandatory */ + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = pdusession_modify_resp_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (pdusession_modify_resp_p->nb_of_pdusessions > 0) { + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModRes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_PDUSessionResourceModifyListModRes; + + for (i = 0; i < pdusession_modify_resp_p->nb_of_pdusessions; i++) { + NGAP_PDUSessionResourceModifyItemModRes_t *item; - /* Retrieve the NGAP gNB instance associated with Mod_id */ - ngap_gNB_instance_p = ngap_gNB_get_instance(instance); - DevAssert(pdusession_modify_resp_p != NULL); - DevAssert(ngap_gNB_instance_p != NULL); - - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - pdusession_modify_resp_p->gNB_ue_ngap_id)) == NULL) { - /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ - NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", - pdusession_modify_resp_p->gNB_ue_ngap_id); - return -1; - } - - /* Uplink NAS transport can occur either during an ngap connected state - * or during initial attach (for example: NAS authentication). - */ - if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || - ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { - NGAP_WARN("You are attempting to send NAS data over non-connected " - "gNB ue ngap id: %08x, current state: %d\n", - pdusession_modify_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); - return -1; - } - - /* Prepare the NGAP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceModify; - pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; - pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceModifyResponse; - out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceModifyResponse; - /* mandatory */ - ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_AMF_UE_NGAP_ID; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = pdusession_modify_resp_p->gNB_ue_ngap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* optional */ - if (pdusession_modify_resp_p->nb_of_pdusessions > 0) { - ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModRes; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_PDUSessionResourceModifyListModRes; - - for (i = 0; i < pdusession_modify_resp_p->nb_of_pdusessions; i++) { - NGAP_PDUSessionResourceModifyItemModRes_t *item; + item = (NGAP_PDUSessionResourceModifyItemModRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyItemModRes_t)); + item->pDUSessionID = pdusession_modify_resp_p->pdusessions[i].pdusession_id; - item = (NGAP_PDUSessionResourceModifyItemModRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyItemModRes_t)); - item->pDUSessionID = pdusession_modify_resp_p->pdusessions[i].pdusession_id; - - NGAP_DEBUG("pdusession_modify_resp: modified pdusession ID %ld\n", item->pDUSessionID); - ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceModifyListModRes.list, item); - } - - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + NGAP_DEBUG("pdusession_modify_resp: modified pdusession ID %ld\n", item->pDUSessionID); + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceModifyListModRes.list, item); } - /* optional */ - if (pdusession_modify_resp_p->nb_of_pdusessions_failed > 0) { - ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToModifyListModRes; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_PDUSessionResourceFailedToModifyListModRes; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - for (i = 0; i < pdusession_modify_resp_p->nb_of_pdusessions_failed; i++) { - NGAP_PDUSessionResourceFailedToModifyItemModRes_t *item; - NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t *pdusessionTransfer_p = NULL; - - item = (NGAP_PDUSessionResourceFailedToModifyItemModRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToModifyItemModRes_t)); - item->pDUSessionID = pdusession_modify_resp_p->pdusessions_failed[i].pdusession_id; + /* optional */ + if (pdusession_modify_resp_p->nb_of_pdusessions_failed > 0) { + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToModifyListModRes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_PDUSessionResourceFailedToModifyListModRes; - pdusessionTransfer_p = (NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t)); - pdusessionTransfer_p->cause.present = pdusession_modify_resp_p->pdusessions_failed[i].cause; - - switch(pdusessionTransfer_p->cause.present) { - case NGAP_Cause_PR_radioNetwork: - pdusessionTransfer_p->cause.choice.radioNetwork = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; - break; + for (i = 0; i < pdusession_modify_resp_p->nb_of_pdusessions_failed; i++) { + NGAP_PDUSessionResourceFailedToModifyItemModRes_t *item; + NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t *pdusessionTransfer_p = NULL; + + item = (NGAP_PDUSessionResourceFailedToModifyItemModRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToModifyItemModRes_t)); + item->pDUSessionID = pdusession_modify_resp_p->pdusessions_failed[i].pdusession_id; - case NGAP_Cause_PR_transport: - pdusessionTransfer_p->cause.choice.transport = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; - break; + pdusessionTransfer_p = (NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t)); + pdusessionTransfer_p->cause.present = pdusession_modify_resp_p->pdusessions_failed[i].cause; + + switch(pdusessionTransfer_p->cause.present) { + case NGAP_Cause_PR_radioNetwork: + pdusessionTransfer_p->cause.choice.radioNetwork = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + break; - case NGAP_Cause_PR_nas: - pdusessionTransfer_p->cause.choice.nas = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; - break; + case NGAP_Cause_PR_transport: + pdusessionTransfer_p->cause.choice.transport = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + break; - case NGAP_Cause_PR_protocol: - pdusessionTransfer_p->cause.choice.protocol = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; - break; + case NGAP_Cause_PR_nas: + pdusessionTransfer_p->cause.choice.nas = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + break; - case NGAP_Cause_PR_misc: - pdusessionTransfer_p->cause.choice.misc = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; - break; + case NGAP_Cause_PR_protocol: + pdusessionTransfer_p->cause.choice.protocol = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + break; - case NGAP_Cause_PR_NOTHING: - default: - break; - } + case NGAP_Cause_PR_misc: + pdusessionTransfer_p->cause.choice.misc = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + break; - memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceModifyUnsuccessfulTransfer, pdusessionTransfer_p); - item->pDUSessionResourceModifyUnsuccessfulTransfer.buf = res.buffer; - item->pDUSessionResourceModifyUnsuccessfulTransfer.size = res.result.encoded; + case NGAP_Cause_PR_NOTHING: + default: + break; + } - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceModifyUnsuccessfulTransfer, pdusessionTransfer_p); + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceModifyUnsuccessfulTransfer, pdusessionTransfer_p); + item->pDUSessionResourceModifyUnsuccessfulTransfer.buf = res.buffer; + item->pDUSessionResourceModifyUnsuccessfulTransfer.size = res.result.encoded; - - NGAP_DEBUG("pdusession_modify_resp: failed pdusession ID %ld\n", item->pDUSessionID); - ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceFailedToModifyListModRes.list, item); - } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceModifyUnsuccessfulTransfer, pdusessionTransfer_p); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + NGAP_DEBUG("pdusession_modify_resp: failed pdusession ID %ld\n", item->pDUSessionID); + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceFailedToModifyListModRes.list, item); } - /* optional */ - if (0) { - ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_CriticalityDiagnostics; - // ie->value.choice.CriticalityDiagnostics = ; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - fprintf(stderr, "start encode\n"); + /* optional */ + if (0) { + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { - NGAP_ERROR("Failed to encode uplink transport\n"); - /* Encode procedure has failed... */ - return -1; - } + fprintf(stderr, "start encode\n"); - MSC_LOG_TX_MESSAGE( - MSC_NGAP_GNB, - MSC_NGAP_AMF, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" E_RAN Modify successful Outcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - pdusession_modify_resp_p->gNB_ue_ngap_id, - ue_context_p->amf_ue_ngap_id); - /* UE associated signalling -> use the allocated stream */ - ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, - ue_context_p->amf_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode uplink transport\n"); + /* Encode procedure has failed... */ + return -1; + } - return 0; + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" E_RAN Modify successful Outcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + pdusession_modify_resp_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + + return 0; } //------------------------------------------------------------------------------ int ngap_gNB_pdusession_release_resp(instance_t instance, ngap_pdusession_release_resp_t *pdusession_release_resp_p) //------------------------------------------------------------------------------ { - ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; - struct ngap_gNB_ue_context_s *ue_context_p = NULL; - NGAP_NGAP_PDU_t pdu; - NGAP_PDUSessionResourceReleaseResponse_t *out; - NGAP_PDUSessionResourceReleaseResponseIEs_t *ie; - uint8_t *buffer = NULL; - uint32_t length; - int i; - /* Retrieve the NGAP gNB instance associated with Mod_id */ - ngap_gNB_instance_p = ngap_gNB_get_instance(instance); - DevAssert(pdusession_release_resp_p != NULL); - DevAssert(ngap_gNB_instance_p != NULL); + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_PDUSessionResourceReleaseResponse_t *out; + NGAP_PDUSessionResourceReleaseResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(pdusession_release_resp_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); - if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, - pdusession_release_resp_p->gNB_ue_ngap_id)) == NULL) { - /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ - NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", - pdusession_release_resp_p->gNB_ue_ngap_id); - return -1; - } + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + pdusession_release_resp_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", + pdusession_release_resp_p->gNB_ue_ngap_id); + return -1; + } - /* Prepare the NGAP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceRelease; - pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; - pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceReleaseResponse; - out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceReleaseResponse; - /* mandatory */ + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceRelease; + pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceReleaseResponse; + out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceReleaseResponse; + /* mandatory */ + ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) { ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes; ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_AMF_UE_NGAP_ID; - asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_RAN_UE_NGAP_ID; - ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes; - /* optional */ - if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) { - ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes; - - for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) { - NGAP_PDUSessionResourceReleasedItemRelRes_t *item; - item = (NGAP_PDUSessionResourceReleasedItemRelRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleasedItemRelRes_t)); - - item->pDUSessionID = pdusession_release_resp_p->pdusession_release[i].pdusession_id; - NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID); - ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceReleasedListRelRes.list, item); - } - - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) { + NGAP_PDUSessionResourceReleasedItemRelRes_t *item; + item = (NGAP_PDUSessionResourceReleasedItemRelRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleasedItemRelRes_t)); + + item->pDUSessionID = pdusession_release_resp_p->pdusession_release[i].pdusession_id; + NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID); + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceReleasedListRelRes.list, item); } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { - NGAP_ERROR("Failed to encode release response\n"); - /* Encode procedure has failed... */ - return -1; - } - MSC_LOG_TX_MESSAGE( - MSC_NGAP_GNB, - MSC_NGAP_AMF, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" E_RAN Release successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %lu", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - pdusession_release_resp_p->gNB_ue_ngap_id, - (uint64_t)ue_context_p->amf_ue_ngap_id); - /* UE associated signalling -> use the allocated stream */ - ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, - ue_context_p->amf_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); - NGAP_INFO("pdusession_release_response sended gNB_UE_NGAP_ID %u amf_ue_ngap_id %lu nb_of_pdusessions_released %d nb_of_pdusessions_failed %d\n", - pdusession_release_resp_p->gNB_ue_ngap_id, (uint64_t)ue_context_p->amf_ue_ngap_id,pdusession_release_resp_p->nb_of_pdusessions_released,pdusession_release_resp_p->nb_of_pdusessions_failed); + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode release response\n"); + /* Encode procedure has failed... */ + return -1; + } - return 0; + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" E_RAN Release successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %lu", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + pdusession_release_resp_p->gNB_ue_ngap_id, + (uint64_t)ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + NGAP_INFO("pdusession_release_response sended gNB_UE_NGAP_ID %u amf_ue_ngap_id %lu nb_of_pdusessions_released %d nb_of_pdusessions_failed %d\n", + pdusession_release_resp_p->gNB_ue_ngap_id, (uint64_t)ue_context_p->amf_ue_ngap_id,pdusession_release_resp_p->nb_of_pdusessions_released,pdusession_release_resp_p->nb_of_pdusessions_failed); + + return 0; } int ngap_gNB_path_switch_req(instance_t instance, diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index c703501847..2a153acaa2 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -89,6 +89,7 @@ uint32_t s1ap_generate_eNB_id(void) { static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, net_ip_address_t *mme_ip_address, + uint16_t mme_port, net_ip_address_t *local_ip_addr, uint16_t in_streams, uint16_t out_streams, @@ -102,7 +103,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, DevAssert(mme_ip_address != NULL); message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; - sctp_new_association_req_p->port = S1AP_PORT_NUMBER; + sctp_new_association_req_p->port = mme_port; sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; sctp_new_association_req_p->in_streams = in_streams; sctp_new_association_req_p->out_streams = out_streams; @@ -221,6 +222,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * /* Trying to connect to provided list of MME ip address */ for (index = 0; index < s1ap_register_eNB->nb_mme; index++) { net_ip_address_t *mme_ip = &s1ap_register_eNB->mme_ip_address[index]; + uint16_t mme_port = s1ap_register_eNB->mme_port[index]; struct s1ap_eNB_mme_data_s *mme = NULL; RB_FOREACH(mme, s1ap_mme_map, &new_instance->s1ap_mme_head) { /* Compare whether IPv4 and IPv6 information is already present, in which @@ -235,6 +237,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * continue; s1ap_eNB_register_mme(new_instance, mme_ip, + mme_port, &s1ap_register_eNB->enb_ip_address, s1ap_register_eNB->sctp_in_streams, s1ap_register_eNB->sctp_out_streams, diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index c668e32d1b..d931e76bb6 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -935,7 +935,7 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance, /* Prepare the S1AP message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_E_RABModify; + pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_E_RABSetup; pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABSetupResponse; out = &pdu.choice.successfulOutcome.value.choice.E_RABSetupResponse; @@ -1032,7 +1032,7 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance, break; } - S1AP_DEBUG("e_rab_modify_resp: failed e_rab ID %ld\n", item->value.choice.E_RABItem.e_RAB_ID); + S1AP_DEBUG("e_rab_setup_resp: failed e_rab ID %ld\n", item->value.choice.E_RABItem.e_RAB_ID); ASN_SEQUENCE_ADD(&ie->value.choice.E_RABList.list, item); } diff --git a/openair3/TEST/test5Gnas.c b/openair3/TEST/test5Gnas.c new file mode 100644 index 0000000000..5124ad6e4d --- /dev/null +++ b/openair3/TEST/test5Gnas.c @@ -0,0 +1,34 @@ +#include +#include + +volatile int oai_exit; + +int main(int argc, char **argv) { + if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + + logInit(); + char *resp; + nr_user_nas_t UErrc= {0}; + NRUEcontext_t UEnas= {0}; + // Network generate identity request after a sucessfull radio attach + int size=identityRequest((void **)&resp, &UEnas); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," identity Request:\n" ); + // UE process the message that it has received from phy layer in a "DL transfer" message + UEprocessNAS(resp, &UErrc); + // UE Scheduler should later call the response + size=identityResponse((void **)&resp, &UErrc); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," identity Response:\n" ); + // Now the gNB process the identity response + processNAS(resp, &UEnas); + // gNB scheduler should call the next query + size=authenticationRequest((void **)&resp, &UEnas); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," authentication request:\n" ); + // as above + UEprocessNAS(resp, &UErrc); + size=authenticationResponse((void **)&resp, &UErrc); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," authentication response:\n" ); + processNAS(resp, &UEnas); + return 0; +} diff --git a/openair3/UICC/usim_interface.c b/openair3/UICC/usim_interface.c new file mode 100644 index 0000000000..15a4e2e540 --- /dev/null +++ b/openair3/UICC/usim_interface.c @@ -0,0 +1,92 @@ +/* +* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The OpenAirInterface Software Alliance licenses this file to You under +* the OAI Public License, Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.openairinterface.org/?page_id=698 +* +* Author and copyright: Laurent Thomas, open-cells.com +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*------------------------------------------------------------------------------- +* For more information about the OpenAirInterface (OAI) Software Alliance: +* contact@openairinterface.org +*/ + +#include +#include + +#define UICC_SECTION "uicc" +#define UICC_CONFIG_HELP_OPTIONS " list of comma separated options to interface a simulated (real UICC to be developped). Available options: \n"\ + " imsi: user imsi\n"\ + " key: cyphering key\n"\ + " opc: cyphering OPc\n" +/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* configuration parameters for the rfsimulator device */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define UICC_PARAMS_DESC {\ + {"imsi", "USIM IMSI\n", 0, strptr:&(uicc->imsiStr), defstrval:"", TYPE_STRING, 0 },\ + {"nmc_size" "number of digits in NMC", 0, iptr:&(uicc->nmc_size), defintval:2, TYPE_INT, 0 },\ + {"key", "USIM Ki\n", 0, strptr:&(uicc->keyStr), defstrval:"", TYPE_STRING, 0 },\ + {"opc", "USIM OPc\n", 0, strptr:&(uicc->opcStr), defstrval:"", TYPE_STRING, 0 },\ + {"amf", "USIM amf\n", 0, strptr:&(uicc->amfStr), defstrval:"8000", TYPE_STRING, 0 },\ + {"sqn", "USIM sqn\n", 0, strptr:&(uicc->sqnStr), defstrval:"000000", TYPE_STRING, 0 },\ + }; + +const char *hexTable="0123456789abcdef"; +static inline uint8_t mkDigit(unsigned char in) { + for (int i=0; i<16; i++) + if (in==hexTable[i]) + return i; + LOG_E(SIM,"Impossible hexa input: %c\n",in); + return 0; +} + +static inline void to_hex(char *in, uint8_t *out, int size) { + for (size_t i=0; in[i]!=0 && i < size*2 ; i+=2) { + *out++=(mkDigit(in[i]) << 4) | mkDigit(in[i+1]); + } +} + +uicc_t *init_uicc(char *sectionName) { + uicc_t *uicc=(uicc_t *)calloc(sizeof(uicc_t),1); + paramdef_t uicc_params[] = UICC_PARAMS_DESC; + // here we call usim simulation, but calling actual usim is quite simple + // the code is in open-cells.com => program_uicc open source + // we can read the IMSI from the USIM + // key, OPc, sqn, amf don't need to be read from the true USIM + int ret = config_get( uicc_params,sizeof(uicc_params)/sizeof(paramdef_t),sectionName); + AssertFatal(ret >= 0, "configuration couldn't be performed"); + LOG_I(SIM, "UICC simulation: IMSI=%s, Ki=%s, OPc=%s\n", uicc->imsiStr, uicc->keyStr, uicc->opcStr); + to_hex(uicc->keyStr,uicc->key, sizeof(uicc->key) ); + to_hex(uicc->opcStr,uicc->opc, sizeof(uicc->opc) ); + to_hex(uicc->sqnStr,uicc->sqn, sizeof(uicc->sqn) ); + to_hex(uicc->amfStr,uicc->amf, sizeof(uicc->amf) ); + return uicc; +} + +void uicc_milenage_generate(uint8_t *autn, uicc_t *uicc) { + // here we call usim simulation, but calling actual usim is quite simple + // the code is in open-cells.com => program_uicc open source + milenage_generate(uicc->opc, uicc->amf, uicc->key, + uicc->sqn, uicc->rand, autn, uicc->ik, uicc->ck, uicc->milenage_res); + log_dump(SIM,uicc->opc,sizeof(uicc->opc), LOG_DUMP_CHAR,"opc:"); + log_dump(SIM,uicc->amf,sizeof(uicc->amf), LOG_DUMP_CHAR,"amf:"); + log_dump(SIM,uicc->key,sizeof(uicc->key), LOG_DUMP_CHAR,"key:"); + log_dump(SIM,uicc->sqn,sizeof(uicc->sqn), LOG_DUMP_CHAR,"sqn:"); + log_dump(SIM,uicc->rand,sizeof(uicc->rand), LOG_DUMP_CHAR,"rand:"); + log_dump(SIM,uicc->ik,sizeof(uicc->ik), LOG_DUMP_CHAR,"milenage output ik:"); + log_dump(SIM,uicc->ck,sizeof(uicc->ck), LOG_DUMP_CHAR,"milenage output ck:"); + log_dump(SIM,uicc->milenage_res,sizeof(uicc->milenage_res), LOG_DUMP_CHAR,"milenage output res:"); + log_dump(SIM,autn,sizeof(autn), LOG_DUMP_CHAR,"milenage output autn:"); +} + diff --git a/openair3/UICC/usim_interface.h b/openair3/UICC/usim_interface.h new file mode 100644 index 0000000000..e8f241c1e8 --- /dev/null +++ b/openair3/UICC/usim_interface.h @@ -0,0 +1,71 @@ +/* +* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The OpenAirInterface Software Alliance licenses this file to You under +* the OAI Public License, Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.openairinterface.org/?page_id=698 +* +* Author and copyright: Laurent Thomas, open-cells.comopenair3/UICC/usim_interface.h +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*------------------------------------------------------------------------------- +* For more information about the OpenAirInterface (OAI) Software Alliance: +* contact@openairinterface.org +*/ +#ifndef USIM_INTERFACE_H +#define USIM_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common_lib.h" + +/* 3GPP glossary +RES RESponse +XRES eXpected RESponse +HRES Hash RESponse +HXRES Hash eXpected RESponse +So, RES can be either milenage res, or received response, so hash of milenage res +*/ + +typedef struct { + char *imsiStr; + char *keyStr; + char *opcStr; + char *amfStr; + char *sqnStr; + uint8_t key[16]; + uint8_t opc[16]; + uint8_t amf[2]; + uint8_t sqn[6]; + int nmc_size; + uint8_t rand[16]; + uint8_t autn[16]; + uint8_t ak[6]; + uint8_t akstar[6]; + uint8_t ck[16]; + uint8_t ik[16]; + uint8_t milenage_res[8]; +} uicc_t; + +/* + * Read the configuration file, section name variable to be able to manage several UICC + */ +uicc_t *init_uicc(char *sectionName); +void uicc_milenage_generate(uint8_t * autn, uicc_t *uicc); +#endif diff --git a/openshift/README.md b/openshift/README.md new file mode 100644 index 0000000000..b7409ab945 --- /dev/null +++ b/openshift/README.md @@ -0,0 +1,107 @@ + + + + + +
+ + + + + + OpenShift Build and Usage Procedures +
+ +----- + +**CAUTION: this is experimental. Still a lot to be done.** + +----- + +# 1. Build pre-requisites # + +To build our RAN images, we SHALL use the `codeready-builder-for-rhel-8-x86_64-rpms` repository with all the proper development libraries. + +This repository is not directly accessible from the UBI RHEL8 image (`registry.access.redhat.com/ubi8/ubi:latest`). + +So we need to copy from a register RHEL8 machine certificates and subsccription manager configuration files. + +SO on a `RHEL8` physical machine (or a virtual machine) connected to the OpenShift Cluster, recover the entitlement and the RH subscription manager configs: + +```bash +oc create configmap rhsm-conf --from-file /etc/rhsm/rhsm.conf +oc create configmap rhsm-ca --from-file /etc/rhsm/ca/redhat-uep.pem + +oc create secret generic etc-pki-entitlement --from-file /etc/pki/entitlement/{NUMBER_ON_YOUR_COMPUTER}.pem --from-file /etc/pki/entitlement/{NUMBER_ON_YOUR_COMPUTER}-key.pem +``` + +These configmaps and secret will be shared by all the build configs in your OC project. No need to do it each time. + +**CAUTION: these files expire every month or so. If you have done a build on your OC project and try again a few weeks later, you may need to re-copy them**. + +```bash +oc delete secret etc-pki-entitlement +oc delete cm rhsm-conf +oc delete cm rhsm-ca +``` + +**LAST POINT: your OC project SHALL be `oai`.** + +# 2. Build the Builder shared image # + +In our Eurecom/OSA environment we need to pass a GIT proxy. + +2 things are impacted by this situation: + +* In `openshift/oai-ran-rh8-build-config.yml` file + * `httpProxy: http://proxy.eurecom.fr:8080` + * `httpsProxy: https://proxy.eurecom.fr:8080` +* Add a environment variable to the build config + +```bash +oc apply -f openshift/oai-ran-rh8-image-stream.yml +oc apply -f openshift/oai-ran-rh8-build-config.yml +oc set env bc/oai-ran-rhel8-build-config NEEDED_GIT_PROXY=http://proxy.eurecom.fr:8080 +oc start-build oai-ran-rhel8-build-config --follow +``` + +In case you do NOT require a GIT proxy: **you SHALL remove the 2 lines in `openshift/oai-ran-rh8-build-config.yml` file.** + +And no need to add a `NEEDED_GIT_PROXY` variable to the build config. + +```bash +oc apply -f openshift/oai-ran-rh8-image-stream.yml +oc apply -f openshift/modified-oai-ran-rh8-build-config.yml +oc start-build oai-ran-rhel8-build-config --follow +``` + +After a while it should be successful. + +# 3. Build an OAI target image # + +For the example the eNB: + +```bash +oc apply -f openshift/oai-enb-rh8-image-stream.yml +oc apply -f openshift/oai-enb-rh8-build-config.yml +oc start-build oai-enb-rh8-build-config --follow +``` + +**CAUTION: if you are pushing modifications to the branch you are using, it won't be taken into account besides the Dockerfile.** + +**Because the source files are copied during the shared image creation.** + +**Only way to regenerate images w/ modified source code is to re-start from step #2.** + +# 4. Deployment using HELM charts # + +**CAUTION: even more experimental.** + +Helm charts are located in another repository: + +```bash +git clone https://github.com/OPENAIRINTERFACE/openair-k8s.git +cd openair-k8s +git checkout helm-deployment-S6a-S1C-S1U-in-network-18-with-enb +helm install mme /path-to-your-cloned/openair-k8s/charts/oai-mme/ +``` diff --git a/openshift/oc_init_enb.sh b/openshift/oc_init_enb.sh deleted file mode 100644 index 6154363cd9..0000000000 --- a/openshift/oc_init_enb.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -oc apply -f openshift/oai-enb-image-stream.yml -oc apply -f openshift/oai-enb-build-config.yml -oc set env bc/oai-enb-build-config NEEDED_GIT_PROXY=http://proxy.eurecom.fr:8080 -oc start-build oai-enb-build-config --follow diff --git a/openshift/oc_init_gnb.sh b/openshift/oc_init_gnb.sh deleted file mode 100644 index e7a570bb43..0000000000 --- a/openshift/oc_init_gnb.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -oc apply -f openshift/oai-gnb-image-stream.yml -oc apply -f openshift/oai-gnb-build-config.yml -oc set env bc/oai-gnb-build-config NEEDED_GIT_PROXY=http://proxy.eurecom.fr:8080 -oc start-build oai-gnb-build-config --follow diff --git a/openshift/oc_init_ran.sh b/openshift/oc_init_ran.sh deleted file mode 100644 index 57dbb662e8..0000000000 --- a/openshift/oc_init_ran.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -oc apply -f openshift/oai-ran-image-stream.yml -oc apply -f openshift/oai-ran-build-config.yml -oc set env bc/oai-ran-build-config NEEDED_GIT_PROXY=http://proxy.eurecom.fr:8080 -oc start-build oai-ran-build-config --follow diff --git a/targets/ARCH/ETHERNET/benetel/4g/benetel.c b/targets/ARCH/ETHERNET/benetel/4g/benetel.c index 37f55c689f..76855111e1 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/4g/benetel.c @@ -207,7 +207,7 @@ next: uint16_t *in; uint16_t *out; in = (uint16_t *)s->buffers.prach[*subframe]; - out = (uint16_t *)ru->prach_rxsigF[antenna]; + out = (uint16_t *)ru->prach_rxsigF[0][antenna]; for (i = 0; i < 840*2; i++) out[i] = ntohs(in[i]); s->buffers.prach_busy[*subframe] = 0; diff --git a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c index 9b64f01d44..42953d1d4a 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c @@ -86,10 +86,9 @@ static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; static struct rte_eth_conf port_conf = { .rxmode = { .split_hdr_size = 0, - .offloads = DEV_RX_OFFLOAD_CRC_STRIP, - .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, - .split_hdr_size = 0, - .max_rx_pkt_len = 9500, + .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, + .split_hdr_size = 0, + .max_rx_pkt_len = 9500, }, .txmode = { .mq_mode = ETH_MQ_TX_NONE, diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index c1ae1afcc7..2f60e7dc49 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -215,7 +215,7 @@ next: uint16_t *in; uint16_t *out; in = (uint16_t *)s->buffers.prach[*slot]; - out = (uint16_t *)ru->prach_rxsigF[antenna]; + out = (uint16_t *)ru->prach_rxsigF[0][antenna]; for (i = 0; i < 839*2; i++) out[i] = ntohs(in[i]); s->buffers.prach_busy[*slot] = 0; @@ -275,6 +275,7 @@ void benetel_fh_if4p5_south_out(RU_t *ru, int slot, uint64_t timestamp) { + //printf("XXX benetel_fh_if4p5_south_out %d %d %ld\n", frame, slot, timestamp); benetel_eth_state_t *s = ru->ifdevice.priv; NR_DL_FRAME_PARMS *fp; diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c index b90702d331..dd50603ec5 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c @@ -86,10 +86,9 @@ static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; static struct rte_eth_conf port_conf = { .rxmode = { .split_hdr_size = 0, - .offloads = DEV_RX_OFFLOAD_CRC_STRIP, - .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, - .split_hdr_size = 0, - .max_rx_pkt_len = 9500, + .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, + .split_hdr_size = 0, + .max_rx_pkt_len = 9500, }, .txmode = { .mq_mode = ETH_MQ_TX_NONE, @@ -234,7 +233,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } // Trigger start send DL packets - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && SYMBOL == 0x46 && ANT_NUM == 0x00 && SUBFRAME == 0x00 && dl_start == 0){ + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && SYMBOL == 0x44 && ANT_NUM == 0x00 && SUBFRAME == 0x00 && dl_start == 0){ printf("\nU-Plane Started\n"); printf("\n====================================================\n"); @@ -253,7 +252,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) p.antenna = 0; memcpy(p.iq, IQ_ptr, 5088); store_ul(bs, &p); - //if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol); + // if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol); } // U-PLANE UL ANT_0 PROCESSING @@ -268,7 +267,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) int tx_frame = frame; int tx_subframe = subframe; int tx_slot = slot; - int tx_symbol = symbol + 8; + int tx_symbol = symbol + 10; if (tx_symbol > 13) { tx_symbol -= 14; @@ -286,7 +285,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) ANT_NUM = 0x00; // Mask the symbol bits from UL packet received and apply the shift. - SYMBOL = ((SYMBOL & 0b00111111) + 8) % 14; + SYMBOL = ((SYMBOL & 0b00111111) + 10) % 14; ANT_NUM = 0x00; SUBFRAME = sf; @@ -307,6 +306,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) memcpy(IQ_ptr, bs->buffers->dl[oai_slot] + tx_symbol * 1272*4, 1272*4); } +//printf("DL buffer f sf slot symbol %d %d %d %d (sf %d)\n", tx_frame, tx_subframe, tx_slot, tx_symbol, (int)sf); bs->buffers->dl_busy[oai_slot] &= ~(1 << tx_symbol); unlock_dl_buffer(bs->buffers, oai_slot); @@ -319,7 +319,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) { // Mask the symbol bits from UL packet received and apply the shift. - SYMBOL = ((SYMBOL & 0b00111111) + 8) % 14; + SYMBOL = ((SYMBOL & 0b00111111) +10) % 14; ANT_NUM = 0x01; SUBFRAME = sf; @@ -348,10 +348,10 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) else if(PAYLOAD_1 == 0x0d && PAYLOAD_2 == 0x28){ if (ANT_NUM == 0) { int subframe = SUBFRAME >> 4; - int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); + //int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); if (subframe==9) { //printf("store prach f.sf.sl %d.%d.%d %d\n", FRAME, subframe, slot, subframe * 2 + slot); - store_prach(bs, FRAME, slot /*subframe * 2 + slot*/, IQ_ptr); + store_prach(bs, FRAME, subframe * 2 + 1, IQ_ptr); } } rte_pktmbuf_free(m); diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.c b/targets/ARCH/ETHERNET/benetel/5g/low.c index 984e401421..52c9f24127 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low.c +++ b/targets/ARCH/ETHERNET/benetel/5g/low.c @@ -27,17 +27,50 @@ void store_ul(benetel_t *bs, ul_packet_t *ul) { +#if 0 +struct timespec t; +static struct timespec old; +clock_gettime(CLOCK_REALTIME, &t); +printf("store_ul %d.%ld (%ld)\n", (int)(t.tv_sec % 60), t.tv_nsec, t.tv_nsec - old.tv_nsec); +old = t; +#endif + /* only antenna 0 for the moment */ if (ul->antenna != 0) return; if (ul->slot != bs->next_slot || ul->symbol != bs->next_symbol) { - printf("%s: fatal, expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", + printf("%s: error, expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", __FUNCTION__, bs->expected_benetel_frame, bs->next_slot, bs->next_symbol, ul->frame, ul->slot, ul->symbol); - exit(1); + } + + /* fill missing data with 0s */ + while (ul->slot != bs->next_slot || + ul->symbol != bs->next_symbol) { + lock_ul_buffer(bs->buffers, bs->next_slot); + if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) { + printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + bs->next_slot, bs->next_symbol); + } + + memset(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + 0, 1272*4); + bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol); + signal_ul_buffer(bs->buffers, bs->next_slot); + unlock_ul_buffer(bs->buffers, bs->next_slot); + + bs->next_symbol++; + if (bs->next_symbol == 14) { + bs->next_symbol = 0; + bs->next_slot = (bs->next_slot + 1) % 20; + if (bs->next_slot == 0) { + bs->expected_benetel_frame++; + bs->expected_benetel_frame &= 255; + } + } } lock_ul_buffer(bs->buffers, bs->next_slot); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 0c89a68dd5..dd29d01fae 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -69,7 +69,7 @@ /** @addtogroup _USRP_PHY_RF_INTERFACE_ * @{ */ - +int gpio789=0; extern int usrp_tx_thread; @@ -692,6 +692,12 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); *ptimestamp = s->rx_timestamp; + // push GPIO bits 7-9 from flags_msb + /*s->usrp->set_command_time(uhd::time_spec_t::from_ticks((s->rx_timestamp+(2*nsamps)),s->sample_rate)); + s->usrp->set_gpio_attr("FP0", "OUT", gpio789<<7, 0x380); + s->usrp->clear_command_time(); + gpio789 = (gpio789+1)&7;*/ + if (device->recplay_state != NULL) { // record mode // Copy subframes to memory (later dump on a file) if (device->recplay_state->nb_samples < device->openair0_cfg->recplay_conf->u_sf_max) { diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 93c07a575f..c4760d8aee 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -533,24 +533,24 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi b->headerMode=false; if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS - t->nextTimestamp=b->th.timestamp> nsamps_for_initial ? - b->th.timestamp - nsamps_for_initial : - 0; - b->lastReceivedTS=b->th.timestamp> nsamps_for_initial ? - b->th.timestamp : - nsamps_for_initial; - LOG_W(HW,"UE got first timestamp: starting at %lu\n", t->nextTimestamp); - b->trashingPacket=true; - } else if ( b->lastReceivedTS < b->th.timestamp) { + t->nextTimestamp=b->th.timestamp> nsamps_for_initial ? + b->th.timestamp - nsamps_for_initial : + 0; + b->lastReceivedTS=b->th.timestamp> nsamps_for_initial ? + b->th.timestamp : + nsamps_for_initial; + LOG_W(HW,"UE got first timestamp: starting at %lu\n", t->nextTimestamp); + b->trashingPacket=true; + } else if ( b->lastReceivedTS < b->th.timestamp) { int nbAnt= b->th.nbAnt; if ( b->th.timestamp-b->lastReceivedTS < CirSize ) { - for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) { - for (int a=0; a < nbAnt; a++) { - b->circularBuf[(index*nbAnt+a)%CirSize].r = 0; - b->circularBuf[(index*nbAnt+a)%CirSize].i = 0; + for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) { + for (int a=0; a < nbAnt; a++) { + b->circularBuf[(index*nbAnt+a)%CirSize].r = 0; + b->circularBuf[(index*nbAnt+a)%CirSize].i = 0; + } } - } } else { memset(b->circularBuf, 0, sampleToByte(CirSize,1)); } @@ -567,7 +567,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi // normal case } else { LOG_E(HW, "received data in past: current is %lu, new reception: %lu!\n", b->lastReceivedTS, b->th.timestamp); - b->trashingPacket=true; + b->trashingPacket=true; } pthread_mutex_lock(&Sockmutex); @@ -646,8 +646,8 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo // We can never write is the past from the received time // So, the node perform receive but will never write these symbols // let's tell this to the opposite node - // We send timestamp for nb samples required - // assuming this should have been done earlier if a Tx would exist + // We send timestamp for nb samples required + // assuming this should have been done earlier if a Tx would exist pthread_mutex_unlock(&Sockmutex); struct complex16 v= {0}; void *samplesVoid[t->tx_num_channels]; @@ -655,18 +655,18 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo for ( int i=0; i < t->tx_num_channels; i++) samplesVoid[i]=(void *)&v; - LOG_I(HW, "No samples Tx occured, so we send 1 sample to notify it: Tx:%lu, Rx:%lu\n", - t->lastWroteTS, t->nextTimestamp); + LOG_I(HW, "No samples Tx occured, so we send 1 sample to notify it: Tx:%lu, Rx:%lu\n", + t->lastWroteTS, t->nextTimestamp); rfsimulator_write_internal(t, t->nextTimestamp, samplesVoid, 1, t->tx_num_channels, 1, true); } else { - pthread_mutex_unlock(&Sockmutex); + pthread_mutex_unlock(&Sockmutex); LOG_W(HW, "trx_write came from another thread\n"); } } else pthread_mutex_unlock(&Sockmutex); - + bool have_to_wait; do { @@ -765,7 +765,7 @@ int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cf int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { return 0; } -int rfsimulator_write_init(openair0_device *device){ +int rfsimulator_write_init(openair0_device *device) { return 0; } __attribute__((__visibility__("default"))) diff --git a/targets/COMMON/create_nr_tasks.c b/targets/COMMON/create_nr_tasks.c deleted file mode 100644 index 94fc6140f6..0000000000 --- a/targets/COMMON/create_nr_tasks.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - - -# include "intertask_interface.h" -# include "create_nr_tasks.h" -# include "common/utils/LOG/log.h" - -# ifdef OPENAIR2 -#include "sctp_eNB_task.h" -#include "ngap_gNB.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 (AMF_MODE_ENABLED) { - if (gnb_nb > 0) { - /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { - LOG_E(SCTP, "Create task for SCTP failed\n"); - return -1; - } - - if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) { - LOG_E(S1AP, "Create task for S1AP failed\n"); - return -1; - }*/ - if(!emulate_rf){ - if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { - LOG_E(UDP_, "Create task for UDP failed\n"); - return -1; - } - } - - if (itti_create_task (TASK_GTPV1_U, >pv1u_eNB_task, NULL) < 0) { - LOG_E(GTPU, "Create task for GTPV1U failed\n"); - return -1; - } - } - - } - - /*if (gnb_nb > 0) { - // Last task to create, others task must be ready before its start - if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { - LOG_E(GNB_APP, "Create task for gNB APP failed\n"); - return -1; - } - }*/ - - - if (gnb_nb > 0) { - LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); - - if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); - return -1; - } - } - - - itti_wait_ready(0); - - return 0; -} -//#endif diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index aa99eee048..ad98a6091b 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -8,23 +8,11 @@ # define NUMBER_OF_NR_RU_MAX 2 # ifndef PHYSIM # ifndef UE_EXPANSION -// TODO:L2 FAPI simulator. -// UESIM_EXPANSION is used to be same value of NUMBER_OF_UE_MAX -// in eNB and UE. -// now , if we use --mu option in UE, compiling error will occur. -// This problem will be fixed in the future. -# ifndef UESIM_EXPANSION # define NUMBER_OF_UE_MAX 4 # define NUMBER_OF_NR_UE_MAX 4 # define NUMBER_OF_UCI_VARS_MAX 14 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 -# else -# define NUMBER_OF_UE_MAX 256 -# define NUMBER_OF_UCI_VARS_MAX 256 -# define NUMBER_OF_CONNECTED_eNB_MAX 1 -# define NUMBER_OF_CONNECTED_gNB_MAX 3 -# endif # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_UCI_VARS_MAX 256 @@ -32,7 +20,8 @@ # define NUMBER_OF_CONNECTED_gNB_MAX 1 # endif # else -# define NUMBER_OF_UE_MAX 1 +# define NUMBER_OF_UE_MAX 4 +# define NUMBER_OF_NR_UE_MAX 4 # define NUMBER_OF_UCI_VARS_MAX 56 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 @@ -48,17 +37,10 @@ eNB process will exit because unexpected access happens. Now some parts are using NUMBER_OF_UE_MAX and the other are using MAX_MOBILES_PER_ENB in for-loop. */ -# ifndef UESIM_EXPANSION # define NUMBER_OF_UE_MAX 16 # define NUMBER_OF_UCI_VARS_MAX 56 # define NUMBER_OF_CONNECTED_eNB_MAX 3 # define NUMBER_OF_CONNECTED_gNB_MAX 3 -# else -# define NUMBER_OF_UE_MAX 256 -# define NUMBER_OF_UCI_VARS_MAX 256 -# define NUMBER_OF_CONNECTED_eNB_MAX 1 -# define NUMBER_OF_CONNECTED_gNB_MAX 3 -# endif # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_UCI_VARS_MAX 256 diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf index 0e3b9fffdf..49b4e4441e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf @@ -139,6 +139,8 @@ eNBs = discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + //SSB central frequency of NR secondary cell group (for ENDC NSA) + nr_scg_ssb_freq = 640000; } ); @@ -174,14 +176,14 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.61.195"; + mme_ip_address = ( { ipv4 = "192.168.18.99"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; } ); - enable_measurement_reports = "no"; + enable_measurement_reports = "yes"; ///X2 enable_x2 = "yes"; @@ -193,9 +195,9 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.160.46"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.196"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.160.46"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.18.196"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.1"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 @@ -226,7 +228,7 @@ RUs = ( { //local_if_name = "enp129s0f0"; local_if_name = "dpdk"; - sdr_addrs = "softmodem -m 2048 -l 8 -n 2 -b 0000:3b:00.0 --proc-type auto --file-prefix ggg -- -p 0x1"; + sdr_addrs = "softmodem -m 2048 -l 35 -n 2 -b 0000:81:00.3 --proc-type auto --file-prefix ggg -- -p 0x1"; #sdr_addrs = "softmodem -l 8 -n 2 -- -p 0x2"; remote_address = "127.0.0.2"; local_address = "127.0.0.1"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 5e02f16b02..037de199df 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -23,6 +23,8 @@ gNBs = ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts = 1; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; servingCellConfigCommon = ( { @@ -203,7 +205,7 @@ gNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.61.195"; + mme_ip_address = ( { ipv4 = "192.168.18.99"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -227,9 +229,9 @@ gNBs = { GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.160.146/24"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.195/24"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "192.168.160.146/24"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.195/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 GNB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; GNB_PORT_FOR_X2C = 36422; # Spec 36422 @@ -267,7 +269,7 @@ RUs = ( clock_src = "external"; local_if_name = "dpdk"; - sdr_addrs = "softmodem -m 2048 -l 6 -n 3 -b 0000:3b:00.1 --proc-type auto --file-prefix hhh -- -p 0x1"; + sdr_addrs = "softmodem -m 2048 -l 34 -n 3 -b 0000:81:00.2 --proc-type auto --file-prefix hhh -- -p 0x1"; remote_address = "127.0.0.2"; local_address = "127.0.0.1"; local_portc = 50000; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index 983404e459..ea38aba1b2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf @@ -170,11 +170,11 @@ gNBs = # pattern1 # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 - dl_UL_TransmissionPeriodicity = 5; - nrofDownlinkSlots = 10; - nrofDownlinkSymbols = 0; - nrofUplinkSlots = 10; - nrofUplinkSymbols = 0; + dl_UL_TransmissionPeriodicity = 3; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; ssPBCH_BlockPower = 10; } @@ -238,7 +238,9 @@ RUs = ( max_rxgain = 75; eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; - if_freq = 5300000000; + if_freq = 5300000000L; + #time_source = "external"; + clock_source = "external"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf index e171b2faa9..82b941ea0e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf @@ -13,7 +13,7 @@ gNBs = gNB_name = "gNB-Eurecom-5GNRBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = 600; + tracking_area_code = 1; plmn_list = ({mcc = 311; mnc = 480; mnc_length = 3;}); @@ -23,6 +23,8 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; servingCellConfigCommon = ( { @@ -71,6 +73,11 @@ gNBs = initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) + initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 261; @@ -89,7 +96,7 @@ gNBs = initialULBWPsubcarrierSpacing = 3; #rach-ConfigCommon #rach-ConfigGeneric - prach_ConfigurationIndex = 98; + prach_ConfigurationIndex = 52; #prach_msg1_FDM #0 = one, 1=two, 2=four, 3=eight prach_msg1_FDM = 0; @@ -103,12 +110,12 @@ gNBs = powerRampingStep = 1; #ra_ReponseWindow #1,2,4,8,10,20,40,80 - ra_ResponseWindow = 4; + ra_ResponseWindow = 7; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR #0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 - ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 7; #ra_ContentionResolutionTimer #(0..7) 8,16,24,32,40,48,56,64 ra_ContentionResolutionTimer = 7; @@ -119,7 +126,7 @@ gNBs = prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # - msg1_SubcarrierSpacing = 1, + msg1_SubcarrierSpacing = 3, # restrictedSetConfig # 0=unrestricted, 1=restricted type A, 2=restricted type B @@ -135,6 +142,10 @@ gNBs = # 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; @@ -148,7 +159,7 @@ gNBs = # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 3; - ssb_PositionsInBurst_Bitmap = 0x100000001L; + ssb_PositionsInBurst_Bitmap = 0x0001000100010001L; # ssb_periodicityServingCell # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 @@ -170,11 +181,11 @@ gNBs = # pattern1 # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 - dl_UL_TransmissionPeriodicity = 5; - nrofDownlinkSlots = 10; - nrofDownlinkSymbols = 0; - nrofUplinkSlots = 10; - nrofUplinkSymbols = 0; + dl_UL_TransmissionPeriodicity = 3; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; ssPBCH_BlockPower = 10; } @@ -192,21 +203,36 @@ gNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "192.168.18.99"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; } ); + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "192.168.18.199"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + NETWORK_INTERFACES : { GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.198/24"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.198/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "192.168.18.198/24"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); @@ -239,6 +265,8 @@ RUs = ( eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; if_freq = 5124520000L; + clock_src = "external"; + time_src = "external"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf new file mode 100644 index 0000000000..9e13d493a8 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf @@ -0,0 +1,284 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 2150 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 433096; + dl_frequencyBand = 66; + # this is 2150 MHz + dl_absoluteFrequencyPointA = 430000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 + initialDLBWPstartSymbolAndLength_3 = 57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 66; + ul_absoluteFrequencyPointA = 350000; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; + clock_src = "external"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf new file mode 100644 index 0000000000..831f9c7978 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf @@ -0,0 +1,284 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 2150 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 433096; + dl_frequencyBand = 66; + # this is 2150 MHz + dl_absoluteFrequencyPointA = 430000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 + initialDLBWPstartSymbolAndLength_3 = 57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 66; + ul_absoluteFrequencyPointA = 350000; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + sdr_addrs = "type=x300"; + clock_src = "external"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 60acb20ecb..56078029af 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -23,7 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; - + servingCellConfigCommon = ( { #spCellConfigCommon @@ -45,7 +45,7 @@ gNBs = dl_carrierBandwidth = 106; #initialDownlinkBWP #genericParameters - # this is RBstart=0,L=50 (275*(L-1))+RBstart + # this is RBstart=41,L=24 (275*(L-1))+RBstart initialDLBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 @@ -74,7 +74,7 @@ gNBs = initialDLBWPk0_3 = 0; initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 + #this is SS=1,L=5 initialDLBWPstartSymbolAndLength_3 = 57; #uplinkConfigCommon @@ -135,18 +135,17 @@ gNBs = initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 6; + + initialULBWPk2_1 = 6; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; initialULBWPmappingType_2 = 1; # this is SS=10 L=4 initialULBWPstartSymbolAndLength_2 = 52; - msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -248,8 +247,15 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 75; eNB_instances = [0]; - #beamforming 1x4 matrix: - bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + ##beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights = [0x00007fff, 0x0000]; + ##beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index 0b04dc82d1..d38fff4241 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -46,7 +46,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=0,L=50 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 13475; + initialDLBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -74,8 +74,9 @@ gNBs = initialDLBWPk0_3 = 0; initialDLBWPmappingType_3 = 0; - #this is SS=1,L=5 + #this is SS=1,L=4 initialDLBWPstartSymbolAndLength_3 = 57; + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -88,7 +89,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 13475; + initialULBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -125,21 +126,26 @@ gNBs = # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # msg1_SubcarrierSpacing = 1, - # restrictedSetConfig # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - initialULBWPk2_1 = 2; + initialULBWPk2_1 = 6; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -242,6 +248,8 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; sdr_addrs = "type=x300"; clock_src = "external"; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_eNB_band13.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_eNB_band13.conf new file mode 100644 index 0000000000..1e32905733 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_eNB_band13.conf @@ -0,0 +1,285 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + # real_time choice in {hard, rt-preempt, no} + real_time = "no"; + ////////// Identification parameters: + eNB_ID = 0xe01; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( + { mcc = 311; mnc = 480; mnc_length = 3; } + ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + nb_antenna_ports = 1; + ue_TransmissionMode = 1; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 13; + downlink_frequency = 751000000L; + uplink_frequency_offset = 31000000; + Nid_cell = 0; + N_RB_DL = 25; //100; + Nid_cell_mbsfn = 0; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + prach_root = 0; + tx_gain = 90; + rx_gain = 115; + pbch_repetition = "FALSE"; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -26; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -96; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; +/* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; +*/ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + //SSB central frequency of NR secondary cell group (for ENDC NSA) + nr_scg_ssb_freq = 2071241; + + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + enable_measurement_reports = "yes"; + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.18.99"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.199/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth1"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.18.199/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.18.199/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="high"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="debug"; + rlc_log_verbosity ="high"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="high"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 160; + puCch10xSnr = 160; + } +); + +THREAD_STRUCT = ( + { + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + worker_config = "ENABLE"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -26; + max_rxgain = 130; + eNB_instances = [0]; + clock_src = "external"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="high"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="high"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="high"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 54a9f4a669..2bf2314f1b 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -95,9 +95,6 @@ pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex -#ifdef UESIM_EXPANSION - uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; -#endif uint16_t sf_ahead=2; int tddflag; char *emul_iface; @@ -543,12 +540,15 @@ void init_pdcp(void) { pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); } +// Stupid function addition because UE itti messages queues definition is common with eNB +void *rrc_enb_process_msg(void *notUsed) { +AssertFatal(false,""); + return NULL; +} + int main( int argc, char **argv ) { int CC_id; uint8_t abstraction_flag=0; -#ifdef UESIM_EXPANSION - memset(inst_pdcp_list, 0, sizeof(inst_pdcp_list)); -#endif // Default value for the number of UEs. It will hold, // if not changed from the command line option --num-ues NB_UE_INST=1;