diff --git a/CHANGELOG.md b/CHANGELOG.md index a9b355d079..c807b7f86a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,71 @@ # RELEASE NOTES: # +## [v2.4.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.4.0) -> December 2025. ## + +General new features and improvements (both RAN and UE): +- Rework LDPC BBdev/AAL interface and support both AMD T2/Intel vRAN Boost + (VRB) 1 accelerators +- Add a taps client for vrtsim real-time simulator (check: vrtsim release?) +- Add new RFemulator virtual radio driver to emulate radio (including noise + generation) for gNB/UE standalone operation +- RLC AM reception improvements for high-throughput scenarios (!3512) +- Small NTN fixes (!3659, !3666, !3581, !3652) +- Improvements to imScope + +Stability and bug fixes: +- RFsimulator: fix concurrency problems during multi-client connection +- USRP driver: support synchronization of USRP B200 +- MAC scheduler improvements +- General L1 improvements for efficiency and stability +- Correct PRS bug and test in CI +- Upgrade Ubuntu container images to Ubuntu 24.04 +- All build system targets compile (`make/ninja all`) +- Minor cleanup, harmonization, and performance improvements all over the stack +- Simplify CI code + +RAN changes (gNB/CU/CU-CP/CU-UP/DU/DU-high/DU-low): +- Support of N2 handover +- Support of "UL-heavy" TDD patterns, e.g., DSUUU +- Open Fronthaul M-plane: CM improvements, PM implementation, and additional + v16.01 support +- Improve interoperability with Nvidia Aerial L1 to support 2 layer UL +- Add O-RAN OSC WLS library as FAPI transport and enable L1/L2 shared memory + split +- Implement FAPI Stop exchange +- Improve interoperability with srsRAN_Project DU +- Add new synchronized real-time data recording application (!3462) +- Support for measurement gaps and general handover fixes +- Support of RRC PDU session release procedure +- Add CU-UP load tester +- Correct BWP scheduling and support multiple BWPs per UE + +nrUE changes: +- Support one additional PDU session (see !3486) +- L3 measurements for A2 measurement reports +- Support for type0 PDSCH frequency allocation +- UE symbol based PDCCH receiver + +Regression or removals: +- No known regressions +- Unused L2 simulator code has been removed +- Unused Benetel radio driver code (not FHI 7.2!) has been removed + +Configuration file changes: +- `gNBs.[0].servingCellConfigCommon.[0].ra_ResponseWindow` is automatically + computed and can be removed +- `gNBs.[0].bwp_list` has been added (moved from entries in + `gNBs.[0].servingCellConfigDedicated`) +- `gNBs.[0].phaseTrackingRS` has been added (moved from entries in + `gNBs.[0].servingCellConfigDedicated`) +- `gNBs.[0].local_s_portc` and `gNBs.[0].remote_s_portc` have no effect and + should be removed +- `gNBs.[0].CSI_report_type` has been added +- `MACRLCs.[0].ulsch_max_frame_inactivity` is automatically computed and can be + removed +- `MACRLCs.[0].local_n_portc` and `MACRLCs.[0].remote_n_portc` have no effect and + should be removed +- `MACRLCs.[0].stats_max_ue` has been added + ## [v2.3.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.3.0) -> July 2025. ## General new features and improvements (both RAN and UE): diff --git a/CMakeLists.txt b/CMakeLists.txt index 2509715244..8f2b1a59ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -464,6 +464,9 @@ target_include_directories(f1ap PUBLIC F1AP_DIR) target_link_libraries(f1ap PUBLIC asn1_f1ap GTPV1U) target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE f1ap_lib) target_include_directories(f1ap PRIVATE ${F1AP_DIR}/lib) +if(E2_AGENT) + target_compile_definitions(f1ap PRIVATE E2_AGENT) +endif() # LPP ############## @@ -978,6 +981,7 @@ set(PHY_SRC_UE ${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_initial_sync_sl.c + ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ntn_l1.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_psbch_rx.c @@ -1037,11 +1041,11 @@ pkg_check_modules(lapacke REQUIRED lapacke) add_library(PHY_UE ${PHY_SRC_UE}) target_link_libraries(PHY_UE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs UTIL) -# RHEL needs also cblas, but Ubuntu does not have it. So `cblas_LIBRARIES` will -# be empty for Ubuntu, a no-op +# RHEL needs also cblas, but Ubuntu does not have it. So `cblas_LIBRARIES` and +# `cblas_INCLUDE_DIRS` will be empty for Ubuntu, a no-op pkg_check_modules(cblas cblas) target_link_libraries(PHY_UE PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES}) -target_include_directories(PHY_UE PRIVATE ${blas_INCLUDE_DIRS} ${lapacke_INCLUDE_DIRS}) +target_include_directories(PHY_UE PRIVATE ${blas_INCLUDE_DIRS} ${cblas_INCLUDE_DIRS} ${lapacke_INCLUDE_DIRS}) add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON}) target_link_libraries(PHY_NR_COMMON PUBLIC UTIL) @@ -1290,6 +1294,9 @@ add_library(L2 ) target_link_libraries(L2 PRIVATE x2ap s1ap lte_rrc m2ap) target_link_libraries(L2 PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) +if(E2_AGENT) + target_compile_definitions(L2 PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT) +endif() add_library(MAC_UE_NR ${MAC_NR_SRC_UE}) target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs PUBLIC nr_ue_power_procedures nr_ue_ra_procedures) @@ -1305,6 +1312,9 @@ add_library(L2_NR target_link_libraries(L2_NR PRIVATE ds alg) target_link_libraries(L2_NR PRIVATE f1ap_lib) target_include_directories(L2_NR PRIVATE ${F1AP_DIR}/lib) +if(E2_AGENT) + target_compile_definitions(L2_NR PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT) +endif() add_library(e1_if ${NR_RRC_DIR}/cucp_cuup_direct.c @@ -2029,6 +2039,19 @@ target_link_libraries(nr_ulsim PRIVATE ) target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) +add_executable(nr_srssim + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/srssim.c + ${OPENAIR_DIR}/executables/softmodem-common.c + ${NFAPI_USER_DIR}/nfapi.c + ${NFAPI_USER_DIR}/gnb_ind_vars.c + ${PHY_INTERFACE_DIR}/queue_t.c + ) + +target_link_libraries(nr_srssim PRIVATE + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc L2_NR -lz -Wl,--end-group + m pthread ITTI dl nr_ue_phy_meas physim_common + ) + # these simulators do not compile: # dlsim_tm7 pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim foreach(myExe dlsim ulsim) @@ -2077,7 +2100,7 @@ if (${T_TRACER}) nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim - nr_ulschsim ldpctest polartest smallblocktest + nr_ulschsim ldpctest polartest smallblocktest nr_srssim #all "add_library" definitions ITTI lte_rrc nr_rrc s1ap x2ap m2ap m3ap f1ap params_libconfig diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index a2bb8112fc..e395973b25 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -380,6 +380,29 @@ pipeline { } } } + stage ("VRT-Sim-Test-5G") { + when { expression {do5Gtest || do5GUeTest} } + steps { + script { + triggerSlaveJob ('RAN-VRT-Sim-Test-5G', 'VRT-Sim-Test-5G') + } + } + post { + always { + script { + // Using a unique variable name for each test stage to avoid overwriting on a global variable + // due to parallel-time concurrency + vrtSim5GStatus = finalizeSlaveJob('RAN-VRT-Sim-Test-5G') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + failingStages += vrtSim5GStatus + } + } + } + } stage ("RF-Sim-Test-5G") { when { expression {do5Gtest || do5GUeTest} } steps { diff --git a/ci-scripts/Jenkinsfile-cluster b/ci-scripts/Jenkinsfile-cluster deleted file mode 100644 index 174ccab62f..0000000000 --- a/ci-scripts/Jenkinsfile-cluster +++ /dev/null @@ -1,228 +0,0 @@ -#!/bin/groovy -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -// Location of the executor node -def pythonExecutor = params.pythonExecutor - -// Location of the test XML file to be run -def testXMLFile = params.pythonTestXmlFile -def mainPythonAllXmlFiles = "" -def buildStageStatus = true - -// Name of the test stage -def testStageName = params.pipelineTestStageName - -// Name of the resource -def lockResources = [] -if (params.LockResources != null && params.LockResources.trim().length() > 0) - params.LockResources.trim().split(",").each{lockResources += [resource: it.trim()]} - -// Global Parameters. Normally they should be populated when the master job -// triggers the slave job with parameters -def eNB_Repository -def eNB_Branch -def eNB_CommitID -def eNB_AllowMergeRequestProcess = false -def eNB_TargetBranch - -def directoryExistsGlob(fileNameWithGlob) { - /* if multiple directories match, will join their names and call fileExists() on that */ - def dir = sh returnStdout: true, script: 'find . -name \'' + fileNameWithGlob + '\' -type d' - dir = dir.replaceAll("\n", "").trim() - echo "matching '" + fileNameWithGlob + "' found: '" + dir + "'" - if (dir == "") - return false - return fileExists(dir) -} - -//------------------------------------------------------------------------------- -// Pipeline start -pipeline { - agent { - label pythonExecutor - } - options { - timestamps() - ansiColor('xterm') - lock(extra: lockResources) - } - - stages { - stage("Build Init") { - steps { - // update the build name and description - buildName "${params.eNB_MR}" - buildDescription "Branch : ${params.eNB_Branch}" - } - } - stage ('Verify Parameters') { - steps { - script { - echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' - - JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"' - JOB_TIMESTAMP = JOB_TIMESTAMP.trim() - - def allParametersPresent = true - - // It is already to late to check it - if (params.pythonExecutor != null) { - echo "eNB CI executor node : ${pythonExecutor}" - } - // If not present picking a default Stage Name - if (params.pipelineTestStageName == null) { - // picking default - testStageName = 'Template Test Stage' - } - - if (params.LockResources == null) { - echo "no LockResources given" - allParametersPresent = false - } - if (params.eNB_SourceCodePath == null) { - echo "no eNB_SourceCodePath given" - allParametersPresent = false - } - // the following 4 parameters should be pushed by the master trigger - // if not present, take the job GIT variables (used for developing) - if (params.eNB_Repository == null) { - eNB_Repository = env.GIT_URL - } else { - eNB_Repository = params.eNB_Repository - } - echo "eNB_Repository : ${eNB_Repository}" - if (params.eNB_Branch == null) { - eNB_Branch = env.GIT_BRANCH - } else { - eNB_Branch = params.eNB_Branch - } - echo "eNB_Branch : ${eNB_Branch}" - if (params.eNB_CommitID == null) { - eNB_CommitID = env.GIT_COMMIT - } else { - eNB_CommitID = params.eNB_CommitID - } - echo "eNB_CommitID : ${eNB_CommitID}" - if (params.eNB_mergeRequest != null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { - if (params.eNB_TargetBranch != null) { - eNB_TargetBranch = params.eNB_TargetBranch - } else { - eNB_TargetBranch = 'develop' - } - echo "eNB_TargetBranch : ${eNB_TargetBranch}" - } - } else { - echo "no eNB_mergeRequest given - not merging develop" - } - - if (params.OC_Credentials == null) { - echo "no OC_Credentials given" - allParametersPresent = false - } - if (params.OC_ProjectName == null) { - echo "no OC_ProjectName given" - allParametersPresent = false - } - if (params.pythonTestXmlFile == null) { - echo "no pythonTestXmlFile given" - allParametersPresent = false - } - if (allParametersPresent) { - echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { - sh "git fetch" - sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" - } else { - sh "git fetch" - sh "git checkout -f ${eNB_CommitID}" - } - } else { - echo "Some parameters are missing" - sh "./ci-scripts/fail.sh" - } - } - } - } - - stage ("Deploy and Test") { - steps { - script { - dir ('ci-scripts') { - echo "\u2705 \u001B[32m${testStageName}\u001B[0m" - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " - echo "Test XML file : ${xmlFile}" - } else { - echo "Test XML file ${xmlFile}: no such file" - } - } - withCredentials([ - [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password'] - ]) { - sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}" - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - try { - timeout (time: 60, unit: 'MINUTES') { - sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}" - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - buildStageStatus = false - } - } - } - sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}" - } - } - } - } - } - stage ("Log Collection") { - steps { - script { - dir ('ci-scripts') { - if (directoryExistsGlob("build_log_*")) { - sh "zip -r -qq build_log_${env.BUILD_ID}.zip build_log_*/*" - sh "rm -rf build_log_*/" - archiveArtifacts artifacts: "build_log_${env.BUILD_ID}.zip" - } - if (directoryExistsGlob("test_log_*")) { - sh "zip -r -qq test_log_${env.BUILD_ID}.zip test_log_*/*" - sh "rm -rf test_log_*/" - archiveArtifacts artifacts: "test_log_${env.BUILD_ID}.zip" - } - if (fileExists("test_results.html")) { - sh "mv test_results.html test_results-${env.JOB_NAME}.html" - sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" - archiveArtifacts artifacts: "test_results-${env.JOB_NAME}.html" - } - } - } - } - } - } -} diff --git a/ci-scripts/Jenkinsfile-nrue b/ci-scripts/Jenkinsfile-nrue deleted file mode 100644 index 3f7ef9b9ed..0000000000 --- a/ci-scripts/Jenkinsfile-nrue +++ /dev/null @@ -1,223 +0,0 @@ -#!/bin/groovy -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -// Location of the executor node -def pythonExecutor = params.pythonExecutor - -// Location of the test XML file to be run -def testXMLFile = params.pythonTestXmlFile -def mainPythonAllXmlFiles = "" -def buildStageStatus = true - -// Name of the test stage -def testStageName = params.pipelineTestStageName - -// Name of the resource -def lockResources = [] -if (params.LockResources != null && params.LockResources.trim().length() > 0) - params.LockResources.trim().split(",").each{lockResources += [resource: it.trim()]} - -// Global Parameters. Normally they should be populated when the master job -// triggers the slave job with parameters -def eNB_Repository -def eNB_Branch -def eNB_CommitID -def eNB_AllowMergeRequestProcess = false -def eNB_TargetBranch - -// Flags -def scmEvent = false -def upstreamEvent = false - -//------------------------------------------------------------------------------- -// Pipeline start -pipeline { - agent { - label pythonExecutor - } - options { - timestamps() - ansiColor('xterm') - lock(extra: lockResources) - } - - stages { - stage("Build Init") { - steps { - // update the build name and description - buildName "${params.eNB_MR}" - buildDescription "Branch : ${params.eNB_Branch}" - } - } - stage ('Verify Parameters') { - steps { - script { - echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' - - JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"' - JOB_TIMESTAMP = JOB_TIMESTAMP.trim() - - def allParametersPresent = true - - // It is already to late to check it - if (params.pythonExecutor != null) { - echo "eNB CI executor node : ${pythonExecutor}" - } - // If not present picking a default Stage Name - if (params.pipelineTestStageName == null) { - // picking default - testStageName = 'Template Test Stage' - } - if (params.LockResources == null) { - echo "no LockResources given" - allParametersPresent = false - } - if (params.eNB_SourceCodePath == null) { - allParametersPresent = false - } - // the following 4 parameters should be pushed by the master trigger - // if not present, take the job GIT variables (used for developing) - if (params.eNB_Repository == null) { - eNB_Repository = env.GIT_URL - } else { - eNB_Repository = params.eNB_Repository - } - echo "eNB_Repository : ${eNB_Repository}" - if (params.eNB_Branch == null) { - eNB_Branch = env.GIT_BRANCH - } else { - eNB_Branch = params.eNB_Branch - } - echo "eNB_Branch : ${eNB_Branch}" - if (params.eNB_CommitID == null) { - eNB_CommitID = env.GIT_COMMIT - } else { - eNB_CommitID = params.eNB_CommitID - } - echo "eNB_CommitID : ${eNB_CommitID}" - if (params.eNB_mergeRequest != null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { - if (params.eNB_TargetBranch != null) { - eNB_TargetBranch = params.eNB_TargetBranch - } else { - eNB_TargetBranch = 'develop' - } - echo "eNB_TargetBranch : ${eNB_TargetBranch}" - } - } - - if (params.OC_Credentials == null) { - allParametersPresent = false - } - if (params.OC_ProjectName == null) { - allParametersPresent = false - } - if (allParametersPresent) { - echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { - sh "git fetch" - sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" - } else { - sh "git fetch" - sh "git checkout -f ${eNB_CommitID}" - } - } else { - echo "Some parameters are missing" - sh "./ci-scripts/fail.sh" - } - } - } - } - - stage ("Deploy and Test") { - steps { - script { - dir ('ci-scripts') { - echo "\u2705 \u001B[32m${testStageName}\u001B[0m" - // If not present picking a default XML file - if (params.pythonTestXmlFile == null) { - // picking default - testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' - echo "Test XML file(default): ${testXMLFile}" - mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " - } else { - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " - echo "Test XML file : ${xmlFile}" - } else { - echo "Test XML file ${xmlFile}: no such file" - } - } - } - withCredentials([ - [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password'] - ]) { - sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}" - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - try { - timeout (time: 60, unit: 'MINUTES') { - sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}" - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - buildStageStatus = false - } - } - } - sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}" - } - } - } - } - } - stage ("Log Collection") { - steps { - script { - dir ('ci-scripts') { - // Zipping all archived log files - sh "mkdir test_logs" - sh "mv *.log* test_logs || true" - // Zip all log files matching cmake_targets/{*.log*,log/*} into test_logs_XXXX.zip - if (fileExists('../cmake_targets/log')) { - sh "mv ../cmake_targets/log/* test_logs || true" - } - sh "zip -r -qq test_logs_${env.BUILD_ID}.zip *test_log*/" - sh "rm -rf *test_log*/" - if (fileExists("test_logs_${env.BUILD_ID}.zip")) { - archiveArtifacts artifacts: "test_logs_${env.BUILD_ID}.zip" - } - if (fileExists("test_results.html")) { - sh "mv test_results.html test_results-${env.JOB_NAME}.html" - sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" - archiveArtifacts artifacts: "test_results-${env.JOB_NAME}.html" - } - } - } - } - } - } -} diff --git a/ci-scripts/Jenkinsfile-physim-deploy b/ci-scripts/Jenkinsfile-physim-deploy deleted file mode 100644 index e3d243d07b..0000000000 --- a/ci-scripts/Jenkinsfile-physim-deploy +++ /dev/null @@ -1,224 +0,0 @@ -#!/bin/groovy -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -// Location of the executor node -def pythonExecutor = params.pythonExecutor - -// Location of the test XML file to be run -def testXMLFile = params.pythonTestXmlFile -def mainPythonAllXmlFiles = "" -def buildStageStatus = true - -// Name of the test stage -def testStageName = params.pipelineTestStageName - -// Name of the resource -def lockResources = [] -if (params.LockResources != null && params.LockResources.trim().length() > 0) - params.LockResources.trim().split(",").each{lockResources += [resource: it.trim()]} - -// Global Parameters. Normally they should be populated when the master job -// triggers the slave job with parameters -def eNB_Repository -def eNB_Branch -def eNB_CommitID -def eNB_AllowMergeRequestProcess = false -def eNB_TargetBranch - -// Flags -def scmEvent = false -def upstreamEvent = false - -//------------------------------------------------------------------------------- -// Pipeline start -pipeline { - agent { - label pythonExecutor - } - options { - timestamps() - ansiColor('xterm') - lock(extra: lockResources) - } - - stages { - stage("Build Init") { - steps { - // update the build name and description - buildName "${params.eNB_MR}" - buildDescription "Branch : ${params.eNB_Branch}" - } - } - stage ('Verify Parameters') { - steps { - script { - echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' - - JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"' - JOB_TIMESTAMP = JOB_TIMESTAMP.trim() - - def allParametersPresent = true - - // It is already to late to check it - if (params.pythonExecutor != null) { - echo "eNB CI executor node : ${pythonExecutor}" - } - // If not present picking a default Stage Name - if (params.pipelineTestStageName == null) { - // picking default - testStageName = 'Template Test Stage' - } - - if (params.LockResources == null) { - echo "no LockResources given" - allParametersPresent = false - } - if (params.eNB_SourceCodePath == null) { - allParametersPresent = false - } - // the following 4 parameters should be pushed by the master trigger - // if not present, take the job GIT variables (used for developing) - if (params.eNB_Repository == null) { - eNB_Repository = env.GIT_URL - } else { - eNB_Repository = params.eNB_Repository - } - echo "eNB_Repository : ${eNB_Repository}" - if (params.eNB_Branch == null) { - eNB_Branch = env.GIT_BRANCH - } else { - eNB_Branch = params.eNB_Branch - } - echo "eNB_Branch : ${eNB_Branch}" - if (params.eNB_CommitID == null) { - eNB_CommitID = env.GIT_COMMIT - } else { - eNB_CommitID = params.eNB_CommitID - } - echo "eNB_CommitID : ${eNB_CommitID}" - if (params.eNB_mergeRequest != null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { - if (params.eNB_TargetBranch != null) { - eNB_TargetBranch = params.eNB_TargetBranch - } else { - eNB_TargetBranch = 'develop' - } - echo "eNB_TargetBranch : ${eNB_TargetBranch}" - } - } - - if (params.OC_Credentials == null) { - allParametersPresent = false - } - if (params.OC_ProjectName == null) { - allParametersPresent = false - } - if (allParametersPresent) { - echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { - sh "git fetch" - sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" - } else { - sh "git fetch" - sh "git checkout -f ${eNB_CommitID}" - } - } else { - echo "Some parameters are missing" - sh "./ci-scripts/fail.sh" - } - } - } - } - - stage ("Deploy and Test") { - steps { - script { - dir ('ci-scripts') { - echo "\u2705 \u001B[32m${testStageName}\u001B[0m" - // If not present picking a default XML file - if (params.pythonTestXmlFile == null) { - // picking default - testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' - echo "Test XML file(default): ${testXMLFile}" - mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " - } else { - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " - echo "Test XML file : ${xmlFile}" - } else { - echo "Test XML file ${xmlFile}: no such file" - } - } - } - withCredentials([ - [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password'] - ]) { - sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}" - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - try { - timeout (time: 60, unit: 'MINUTES') { - sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}" - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - buildStageStatus = false - } - } - } - sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}" - } - } - } - } - } - stage ("Log Collection") { - steps { - script { - dir ('ci-scripts') { - // Zipping all archived log files - sh "mkdir test_logs" - sh "mv *.log* test_logs || true" - // Zip all log files matching cmake_targets/{*.log*,log/*} into test_logs_XXXX.zip - if (fileExists('../cmake_targets/log')) { - sh "mv ../cmake_targets/log/* test_logs || true" - } - sh "zip -r -qq test_logs_${env.BUILD_ID}.zip *test_log*/" - sh "rm -rf *test_log*/" - if (fileExists("test_logs_${env.BUILD_ID}.zip")) { - archiveArtifacts artifacts: "test_logs_${env.BUILD_ID}.zip" - } - if (fileExists("test_results.html")) { - sh "mv test_results.html test_results-${env.JOB_NAME}.html" - sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" - archiveArtifacts artifacts: "test_results-${env.JOB_NAME}.html" - } - } - } - } - } - } -} diff --git a/ci-scripts/Jenkinsfile-tmp-full-ran b/ci-scripts/Jenkinsfile-tmp-full-ran deleted file mode 100644 index 07b10ab980..0000000000 --- a/ci-scripts/Jenkinsfile-tmp-full-ran +++ /dev/null @@ -1,250 +0,0 @@ -#!/bin/groovy -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -// Template Jenkins Declarative Pipeline script to run Test w/ RF HW - -// Location of the python executor node shall be in the same subnet as the others servers -def pythonExecutor = params.pythonExecutor - -// Location of the test XML file to be run -def testXMLFile = params.pythonTestXmlFile -def mainPythonAllXmlFiles = "" -def buildStageStatus = true - -// Name of the test stage -def testStageName = params.pipelineTestStageName - -def lockResources = [] -if (params.LockResources != null && params.LockResources.trim().length() > 0) - params.LockResources.trim().split(",").each{lockResources += [resource: it.trim()]} - -// Terminate Status -def termENB = 0 -def termStatusArray = new Boolean[termENB + 1] -termStatusArray[termENB] = false - -// Global Parameters. Normally they should be populated when the master job -// triggers the slave job with parameters -def eNB_Repository -def eNB_Branch -def eNB_CommitID -def eNB_AllowMergeRequestProcess = false -def eNB_TargetBranch - -def doEpcLogCollection = true - - - -pipeline { - agent { - label pythonExecutor - } - options { - ansiColor('xterm') - lock(extra: lockResources) - } - - stages { - stage("Build Init") { - steps { - // update the build name and description - buildName "${params.eNB_MR}" - buildDescription "Branch : ${params.eNB_Branch}" - } - } - stage ("Verify Parameters") { - steps { - script { - echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' - def allParametersPresent = true - - // It is already to late to check it - if (params.pythonExecutor != null) { - echo "eNB CI executor node : ${pythonExecutor}" - } - // If not present picking a default Stage Name - if (params.pipelineTestStageName == null) { - // picking default - testStageName = 'Template Test Stage' - } - - if (params.LockResources == null) { - echo "no LockResources given" - allParametersPresent = false - } - if (params.eNB_SourceCodePath == null) { - allParametersPresent = false - } - // the following 4 parameters should be pushed by the master trigger - // if not present, take the job GIT variables (used for developing) - if (params.eNB_Repository == null) { - eNB_Repository = env.GIT_URL - } else { - eNB_Repository = params.eNB_Repository - } - echo "eNB_Repository : ${eNB_Repository}" - if (params.eNB_Branch == null) { - eNB_Branch = env.GIT_BRANCH - } else { - eNB_Branch = params.eNB_Branch - } - echo "eNB_Branch : ${eNB_Branch}" - if (params.eNB_CommitID == null) { - eNB_CommitID = env.GIT_COMMIT - } else { - eNB_CommitID = params.eNB_CommitID - } - echo "eNB_CommitID : ${eNB_CommitID}" - if (params.eNB_mergeRequest != null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { - if (params.eNB_TargetBranch != null) { - eNB_TargetBranch = params.eNB_TargetBranch - } else { - eNB_TargetBranch = 'develop' - } - echo "eNB_TargetBranch : ${eNB_TargetBranch}" - } - } - - if (allParametersPresent) { - echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { - sh "git fetch" - sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" - } else { - sh "git fetch" - sh "git checkout -f ${eNB_CommitID}" - } - } else { - currentBuild.result = 'ABORTED' - error('Stopping early because some parameters are missing') - } - } - } - } - stage ("Build and Test") { - steps { - script { - dir ('ci-scripts') { - echo "\u2705 \u001B[32m${testStageName}\u001B[0m" - // If not present picking a default XML file - if (params.pythonTestXmlFile == null) { - // picking default - testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' - echo "Test XML file(default): ${testXMLFile}" - mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " - } else { - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " - echo "Test XML file : ${xmlFile}" - } else { - echo "Test XML file ${xmlFile}: no such file" - } - } - } - sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}" - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - try { - timeout (time: 60, unit: 'MINUTES') { - sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile}" - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - buildStageStatus = false - } - } - } - sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}" - } - } - } - } - stage ("Terminate") { - parallel { - stage('Terminate eNB') { - steps { - echo '\u2705 \u001B[32mTerminate eNB\u001B[0m' - sh "python3 ci-scripts/main.py --mode=TerminateeNB" - } - post { - success { - script { - termStatusArray[termENB] = true - } - } - } - } - } - } - stage('Log Collection') { - parallel { - stage('Log Collection (eNB - Run)') { - steps { - echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m' - sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}" - - script { - if(fileExists("enb.log.${env.BUILD_ID}.zip")) { - archiveArtifacts "enb.log.${env.BUILD_ID}.zip" - } - if(fileExists("ci-scripts/test_results.html")) { - sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html" - sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" - archiveArtifacts "test_results-${JOB_NAME}.html" - } - } - } - } - } - } - } - - post { - always { - script { - if (params.pipelineZipsConsoleLog != null) { - if (params.pipelineZipsConsoleLog) { - echo "Archiving Jenkins console log" - sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true" - sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true" - if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) { - archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip" - } - } - } - } - } - // Making sure that we really shutdown every thing before leaving - failure { - script { - if (!termStatusArray[termENB]) { - sh "python3 ci-scripts/main.py --mode=TerminateeNB" - } - } - } - } -} diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb b/ci-scripts/Jenkinsfile-tmp-multi-enb deleted file mode 100644 index c01c8daf7e..0000000000 --- a/ci-scripts/Jenkinsfile-tmp-multi-enb +++ /dev/null @@ -1,225 +0,0 @@ -#!/bin/groovy -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -// Template Jenkins Declarative Pipeline script to run Test w/ RF HW - -// Location of the python executor node shall be in the same subnet as the others servers -def pythonExecutor = params.pythonExecutor - -// Location of the test XML file to be run -def testXMLFile = params.pythonTestXmlFile -def mainPythonAllXmlFiles = "" -def buildStageStatus = true - -// Name of the test stage -def testStageName = params.pipelineTestStageName - -def lockResources = [] -if (params.LockResources != null && params.LockResources.trim().length() > 0) - params.LockResources.trim().split(",").each{lockResources += [resource: it.trim()]} - -// Global Parameters. Normally they should be populated when the master job -// triggers the slave job with parameters -def eNB_Repository -def eNB_Branch -def eNB_CommitID -def eNB_AllowMergeRequestProcess = false -def eNB_TargetBranch - -pipeline { - agent { - label pythonExecutor - } - options { - ansiColor('xterm') - lock(extra: lockResources) - } - stages { - stage("Build Init") { - steps { - // update the build name and description - buildName "${params.eNB_MR}" - buildDescription "Branch : ${params.eNB_Branch}" - } - } - stage ("Verify Parameters") { - steps { - script { - echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' - def allParametersPresent = true - - // It is already to late to check it - if (params.pythonExecutor != null) { - echo "eNB CI executor node : ${pythonExecutor}" - } - // If not present picking a default Stage Name - if (params.pipelineTestStageName == null) { - // picking default - testStageName = 'Template Test Stage' - } - - if (params.LockResources == null) { - echo "no LockResources given" - allParametersPresent = false - } - if (params.eNB_SourceCodePath == null) { - allParametersPresent = false - } - // the following 4 parameters should be pushed by the master trigger - // if not present, take the job GIT variables (used for developing) - if (params.eNB_Repository == null) { - eNB_Repository = env.GIT_URL - } else { - eNB_Repository = params.eNB_Repository - } - echo "eNB_Repository : ${eNB_Repository}" - if (params.eNB_Branch == null) { - eNB_Branch = env.GIT_BRANCH - } else { - eNB_Branch = params.eNB_Branch - } - echo "eNB_Branch : ${eNB_Branch}" - if (params.eNB_CommitID == null) { - eNB_CommitID = env.GIT_COMMIT - } else { - eNB_CommitID = params.eNB_CommitID - } - echo "eNB_CommitID : ${eNB_CommitID}" - if (params.eNB_mergeRequest != null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { - if (params.eNB_TargetBranch != null) { - eNB_TargetBranch = params.eNB_TargetBranch - } else { - eNB_TargetBranch = 'develop' - } - echo "eNB_TargetBranch : ${eNB_TargetBranch}" - } - } - - if (allParametersPresent) { - echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { - sh "git fetch" - sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" - } else { - sh "git fetch" - sh "git checkout -f ${eNB_CommitID}" - } - } else { - echo "Some parameters are missing" - sh "./ci-scripts/fail.sh" - } - } - } - } - stage ("Build and Test") { - steps { - script { - dir ('ci-scripts') { - echo "\u2705 \u001B[32m${testStageName}\u001B[0m" - // If not present picking a default XML file - if (params.pythonTestXmlFile == null) { - // picking default - testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' - echo "Test XML file(default): ${testXMLFile}" - mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " - } else { - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " - echo "Test XML file : ${xmlFile}" - } else { - echo "Test XML file ${xmlFile}: no such file" - } - } - } - sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}" - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - try { - timeout (time: 60, unit: 'MINUTES') { - sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile}" - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - buildStageStatus = false - } - } - } - sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}" - } - } - } - } - stage ("Terminate") { - parallel { - stage('Terminate eNB') { - steps { - echo '\u2705 \u001B[32mTerminate eNB\u001B[0m' - sh "python3 ci-scripts/main.py --mode=TerminateeNB" - } - } - } - } - stage('Log Collection') { - parallel { - stage('Log Collection (eNB - Run)') { - steps { - echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m' - sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}" - - script { - if(fileExists("enb.log.${env.BUILD_ID}.zip")) { - archiveArtifacts "enb.log.${env.BUILD_ID}.zip" - } - if(fileExists("ci-scripts/test_results.html")) { - sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html" - sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" - archiveArtifacts "test_results-${JOB_NAME}.html" - } - } - } - } - } - } - } - - post { - always { - script { - if (params.pipelineZipsConsoleLog != null) { - if (params.pipelineZipsConsoleLog) { - echo "Archiving Jenkins console log" - sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true" - sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true" - if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) { - archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip" - } - } - } - } - } - } -} diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa b/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa deleted file mode 100644 index 67aa6b4511..0000000000 --- a/ci-scripts/Jenkinsfile-tmp-multi-enb-nsa +++ /dev/null @@ -1,216 +0,0 @@ -#!/bin/groovy -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -// Template Jenkins Declarative Pipeline script to run Test w/ RF HW - -// Location of the python executor node shall be in the same subnet as the others servers -def pythonExecutor = params.pythonExecutor - -// Location of the test XML file to be run -def testXMLFile = params.pythonTestXmlFile -def mainPythonAllXmlFiles = "" -def buildStageStatus = true - -// Name of the test stage -def testStageName = params.pipelineTestStageName - -def lockResources = [] -if (params.LockResources != null && params.LockResources.trim().length() > 0) - params.LockResources.trim().split(",").each{lockResources += [resource: it.trim()]} - -// Global Parameters. Normally they should be populated when the master job -// triggers the slave job with parameters -def eNB_Repository -def eNB_Branch -def eNB_CommitID -def eNB_AllowMergeRequestProcess -def eNB_TargetBranch - -//Status fed to the database -def StatusForDb = "" - - -pipeline { - agent {label pythonExecutor} - options { - ansiColor('xterm') - lock(extra: lockResources) - } - stages { - stage("Build Init") { - steps { - // update the build name and description - buildName "${params.eNB_MR}" - buildDescription "Branch : ${params.eNB_Branch}" - } - } - stage ("Verify Parameters") { - steps { - script { - echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' - def allParametersPresent = true - - // It is already to late to check it - if (params.pythonExecutor != null) { - echo "eNB CI executor node : ${pythonExecutor}" - } - // If not present picking a default Stage Name - if (params.pipelineTestStageName == null) { - // picking default - testStageName = 'Template Test Stage' - } - - if (params.LockResources == null) { - echo "no LockResources given" - allParametersPresent = false - } - if (params.eNB_SourceCodePath == null) { - allParametersPresent = false - } - // the following 4 parameters should be pushed by the master trigger - // if not present, take the job GIT variables (used for developing) - if (params.eNB_Repository == null) { - eNB_Repository = env.GIT_URL - } else { - eNB_Repository = params.eNB_Repository - } - echo "eNB_Repository : ${eNB_Repository}" - if (params.eNB_Branch == null) { - eNB_Branch = env.GIT_BRANCH - } else { - eNB_Branch = params.eNB_Branch - } - echo "eNB_Branch : ${eNB_Branch}" - if (params.eNB_CommitID == null) { - eNB_CommitID = env.GIT_COMMIT - } else { - eNB_CommitID = params.eNB_CommitID - } - echo "eNB_CommitID : ${eNB_CommitID}" - if (params.eNB_mergeRequest!= null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { - if (params.eNB_TargetBranch != null) { - eNB_TargetBranch = params.eNB_TargetBranch - } else { - eNB_TargetBranch = 'develop' - } - echo "eNB_TargetBranch : ${eNB_TargetBranch}" - } - } - - if (allParametersPresent) { - echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { - sh "git fetch" - sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" - } else { - sh "git fetch" - sh "git checkout -f ${eNB_CommitID}" - } - } else { - echo "Some parameters are missing" - sh "./ci-scripts/fail.sh" - } - } - } - } - stage ("Build and Test") { - steps { - script { - dir ('ci-scripts') { - echo "\u2705 \u001B[32m${testStageName}\u001B[0m" - // If not present picking a default XML file - if (params.pythonTestXmlFile == null) { - // picking default - testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' - echo "Test XML file(default): ${testXMLFile}" - mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " - } else { - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " - echo "Test XML file : ${xmlFile}" - } else { - echo "Test XML file ${xmlFile}: no such file" - } - } - } - sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}" - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - try { - timeout (time: 60, unit: 'MINUTES') { - sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile}" - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - buildStageStatus = false - } - } - } - sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}" - } - } - } - } - stage('Log Collection') { - parallel { - stage('Log Collection (eNB - Run)') { - steps { - echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m' - sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}" - script { - if(fileExists("enb.log.${env.BUILD_ID}.zip")) { - archiveArtifacts "enb.log.${env.BUILD_ID}.zip" - } - } - } - } - } - } - } - - post { - always { - script { - if(fileExists("ci-scripts/test_results.html")) { - sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html" - sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" - archiveArtifacts "test_results-${JOB_NAME}.html" - } - if (params.pipelineZipsConsoleLog != null) { - if (params.pipelineZipsConsoleLog) { - echo "Archiving Jenkins console log" - sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true" - sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true" - if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) { - archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip" - } - } - } - } - } - } -} diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran deleted file mode 100644 index 526899a5a2..0000000000 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ /dev/null @@ -1,260 +0,0 @@ -#!/bin/groovy -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -// Template Jenkins Declarative Pipeline script to run Test w/ RF HW - -// Location of the python executor node shall be in the same subnet as the others servers -def pythonExecutor = params.pythonExecutor - -// Location of the test XML file to be run -def testXMLFile = params.pythonTestXmlFile -def mainPythonAllXmlFiles = "" -def buildStageStatus = true - -// Name of the test stage -def testStageName = params.pipelineTestStageName - -def lockResources = [] -if (params.LockResources != null && params.LockResources.trim().length() > 0) - params.LockResources.trim().split(",").each{lockResources += [resource: it.trim()]} - -// Terminate Status -def termUE = 0 -def termENB = 1 -def termSPGW = 2 -def termMME = 3 -def termHSS = 4 -def termStatusArray = new Boolean[termHSS + 1] -termStatusArray[termUE] = false -termStatusArray[termENB] = false -termStatusArray[termSPGW] = false -termStatusArray[termMME] = false -termStatusArray[termHSS] = false - -// Global Parameters. Normally they should be populated when the master job -// triggers the slave job with parameters -def eNB_Repository -def eNB_Branch -def eNB_CommitID -def eNB_AllowMergeRequestProcess = false -def eNB_TargetBranch - -def flexricOption = "" - -pipeline { - agent { - label pythonExecutor - } - options { - ansiColor('xterm') - lock(extra: lockResources) - } - stages { - stage("Build Init") { - steps { - // update the build name and description - buildName "${params.eNB_MR}" - buildDescription "Branch : ${params.eNB_Branch}" - } - } - stage ("Verify Parameters") { - steps { - script { - echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' - def allParametersPresent = true - - // It is already to late to check it - if (params.pythonExecutor != null) { - echo "eNB CI executor node : ${pythonExecutor}" - } - // If not present picking a default Stage Name - if (params.pipelineTestStageName == null) { - // picking default - testStageName = 'Template Test Stage' - } - - if (params.LockResources == null) { - echo "no LockResources given" - allParametersPresent = false - } - if (params.eNB_SourceCodePath == null) { - allParametersPresent = false - } - // the following 4 parameters should be pushed by the master trigger - // if not present, take the job GIT variables (used for developing) - if (params.eNB_Repository == null) { - eNB_Repository = env.GIT_URL - } else { - eNB_Repository = params.eNB_Repository - } - echo "eNB_Repository : ${eNB_Repository}" - if (params.eNB_Branch == null) { - eNB_Branch = env.GIT_BRANCH - } else { - eNB_Branch = params.eNB_Branch - } - echo "eNB_Branch : ${eNB_Branch}" - if (params.eNB_CommitID == null) { - eNB_CommitID = env.GIT_COMMIT - } else { - eNB_CommitID = params.eNB_CommitID - } - echo "eNB_CommitID : ${eNB_CommitID}" - if (params.eNB_mergeRequest != null) { - eNB_AllowMergeRequestProcess = params.eNB_mergeRequest - if (eNB_AllowMergeRequestProcess) { - if (params.eNB_TargetBranch != null) { - eNB_TargetBranch = params.eNB_TargetBranch - } else { - eNB_TargetBranch = 'develop' - } - echo "eNB_TargetBranch : ${eNB_TargetBranch}" - } - } - - if (params.Flexric_Tag != null) { - echo "This pipeline is configured to run with a FlexRIC deployment." - echo "Appending FlexRicTag option to the list of options" - flexricOption = "--FlexRicTag=${params.Flexric_Tag}" - echo "Using new Flexric option: ${flexricOption}" - } - - if (allParametersPresent) { - echo "All parameters are present" - if (eNB_AllowMergeRequestProcess) { - sh "git fetch" - sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" - } else if (eNB_CommitID != 'develop') { - sh "git fetch" - sh "git checkout -f ${eNB_CommitID}" - } - } else { - error "Some parameters are missing" - } - } - } - } - stage ("Build and Test") { - steps { - script { - dir ('ci-scripts') { - echo "\u2705 \u001B[32m${testStageName}\u001B[0m" - // If not present picking a default XML file - if (params.pythonTestXmlFile == null) { - // picking default - testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' - echo "Test XML file(default): ${testXMLFile}" - mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " - } else { - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " - echo "Test XML file : ${xmlFile}" - } else { - echo "Test XML file ${xmlFile}: no such file" - } - } - } - sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${flexricOption} ${mainPythonAllXmlFiles}" - String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") - for (xmlFile in myXmlTestSuite) { - if (fileExists(xmlFile)) { - try { - timeout (time: 60, unit: 'MINUTES') { - sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${flexricOption} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile}" - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - buildStageStatus = false - } - } - } - sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}" - } - } - } - } - stage ("Terminate") { - parallel { - stage('Terminate eNB') { - steps { - echo '\u2705 \u001B[32mTerminate eNB\u001B[0m' - sh "python3 ci-scripts/main.py --mode=TerminateeNB" - } - post { - success { - script { - termStatusArray[termENB] = true - } - } - } - } - } - } - stage('Log Collection') { - parallel { - stage('Log Collection (eNB - Run)') { - steps { - echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m' - sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}" - script { - if(fileExists("enb.log.${env.BUILD_ID}.zip")) { - archiveArtifacts "enb.log.${env.BUILD_ID}.zip" - } - if(fileExists("ci-scripts/test_results.html")) { - sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html" - sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" - archiveArtifacts "test_results-${JOB_NAME}.html" - } - } - } - } - } - } - } - - post { - always { - script { - if (params.pipelineZipsConsoleLog != null) { - if (params.pipelineZipsConsoleLog) { - echo "Archiving Jenkins console log" - sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true" - sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true" - if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) { - archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip" - } - } - } - } - } - // Making sure that we really shutdown every thing before leaving - failure { - script { - if (!termStatusArray[termENB]) { - sh "python3 ci-scripts/main.py --mode=TerminateeNB" - } - } - } - } -} diff --git a/ci-scripts/cls_ci_helper.py b/ci-scripts/cls_ci_helper.py index eb47a32892..6b67057c92 100644 --- a/ci-scripts/cls_ci_helper.py +++ b/ci-scripts/cls_ci_helper.py @@ -24,15 +24,14 @@ from typing import NamedTuple import logging class TestCaseCtx(NamedTuple): - count: int - test_id: int + test_idx: int logPath: str def Default(logPath): - return TestCaseCtx(123, 112233, logPath) + return TestCaseCtx(112233, logPath) def baseFilename(self): # typically, the test ID is of form 001234 (6 digits) - return f"{self.logPath}/{self.count}-{self.test_id:06d}" + return f"{self.logPath}/{self.test_idx:06d}" def archiveArtifact(cmd, ctx, remote_path): base = os.path.basename(remote_path) diff --git a/ci-scripts/cls_cluster.py b/ci-scripts/cls_cluster.py index 8a9919c700..dc97c80acd 100644 --- a/ci-scripts/cls_cluster.py +++ b/ci-scripts/cls_cluster.py @@ -164,7 +164,6 @@ class Cluster: def PullClusterImage(self, HTML, node, images, tag_prefix): logging.debug(f'Pull OC image {images} to server {node}') - self.testCase_id = HTML.testCase_id with cls_cmd.getConnection(node) as cmd: succeeded = OC_login(cmd, self.OCUserName, self.OCPassword, CI_OC_RAN_NAMESPACE) if not succeeded: @@ -211,8 +210,6 @@ class Cluster: logging.debug(f'Building on cluster triggered from server: {node}') self.cmd = cls_cmd.RemoteCmd(node) - self.testCase_id = HTML.testCase_id - # Workaround for some servers, we need to erase completely the workspace self.cmd.cd(lSourcePath) # to reduce the amount of data send to OpenShift, we @@ -412,7 +409,7 @@ class Cluster: # the groovy scripts expects all logs in # //ci-scripts, so copy it there with cls_cmd.LocalCmd() as c: - c.run(f'mkdir -p {os.getcwd()}/test_log_{ctx.test_id}/') - c.run(f'cp -r {ctx.logPath} {os.getcwd()}/test_log_{ctx.test_id}/') + c.run(f'mkdir -p {os.getcwd()}/test_log_{ctx.test_idx}/') + c.run(f'cp -r {ctx.logPath} {os.getcwd()}/test_log_{ctx.test_idx}/') return status diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 71e437676c..be42790a5c 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -209,7 +209,7 @@ def CheckLogs(self, filename, HTML, RAN): elif 'nv-cubb' in name: msg = 'Undeploy PNF/Nvidia CUBB' HTML.CreateHtmlTestRow(msg, 'OK', CONST.ALL_PROCESSES_OK) - elif (any(sub in name for sub in ['enb','rru','rcc','cu','du','gnb'])): + elif (any(sub in name for sub in ['enb','rru','rcc','cu','du','gnb','vnf'])): logging.debug(f'\u001B[1m Analyzing XnB logfile {filename}\u001B[0m') logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers) opt = f"xNB log analysis ({name})" diff --git a/ci-scripts/cls_module.py b/ci-scripts/cls_module.py index 17d45828c8..a82e2050b9 100644 --- a/ci-scripts/cls_module.py +++ b/ci-scripts/cls_module.py @@ -111,11 +111,10 @@ class Module_UE: return self._collectTrace(ctx) return None - def attach(self, attach_tries = 3, attach_timeout = 0): + def attach(self, attach_tries = 3, attach_timeout = 40): ip = None while attach_tries > 0: self._command(self.cmd_dict["attach"]) - attach_timeout += 20 timeout = attach_timeout logging.debug("Waiting for IP address to be assigned") ip = self.getIP(silent=False, reportNonZero=True) @@ -126,6 +125,7 @@ class Module_UE: if ip: break logging.warning(f"UE did not receive IP address after {attach_timeout} s, detaching") + attach_timeout += 20 attach_tries -= 1 self._command(self.cmd_dict["detach"]) time.sleep(5) diff --git a/ci-scripts/cls_native.py b/ci-scripts/cls_native.py index d96f60bdca..e1b42acf5b 100644 --- a/ci-scripts/cls_native.py +++ b/ci-scripts/cls_native.py @@ -34,9 +34,8 @@ DPDK_PATH = '/opt/dpdk-t2-22.11.0' class Native(): - def Build(ctx, node, test_case, HTML, directory, options): + def Build(ctx, node, HTML, directory, options): logging.debug(f'Building on server: {node}') - HTML.testCase_id = test_case with cls_cmd.getConnection(node) as ssh: base = f"{directory}/cmake_targets" diff --git a/ci-scripts/cls_oai_html.py b/ci-scripts/cls_oai_html.py index cb1ca56542..6e29063192 100644 --- a/ci-scripts/cls_oai_html.py +++ b/ci-scripts/cls_oai_html.py @@ -67,7 +67,7 @@ class HTMLManagement(): self.htmlUEFailureMsg = '' self.startTime = int(round(time.time() * 1000)) - self.testCase_id = '' + self.testCaseIdx = '' self.desc = '' #----------------------------------------------------------- @@ -191,7 +191,7 @@ class HTMLManagement(): self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') @@ -259,7 +259,7 @@ class HTMLManagement(): currentTime = int(round(time.time() * 1000)) - self.startTime self.htmlFile.write(' \n') self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') if (str(status) == 'OK'): @@ -374,7 +374,7 @@ class HTMLManagement(): addOrangeBK = False self.htmlFile.write(' \n') self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') if (str(status) == 'OK'): diff --git a/ci-scripts/cls_static_code_analysis.py b/ci-scripts/cls_static_code_analysis.py index 63b5b5b6dd..5ed52e4027 100644 --- a/ci-scripts/cls_static_code_analysis.py +++ b/ci-scripts/cls_static_code_analysis.py @@ -88,7 +88,6 @@ class StaticCodeAnalysis(): raise ValueError(f"{lSourcePath=} {node=}") logging.debug('Building on server: ' + node) cmd = cls_cmd.getConnection(node) - self.testCase_id = HTML.testCase_id # on RedHat/CentOS .git extension is mandatory result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) if result is not None: @@ -187,8 +186,6 @@ class StaticCodeAnalysis(): raise ValueError(f"{lSourcePath=} {node=}") logging.debug('Building on server: ' + node) cmd = cls_cmd.getConnection(node) - self.testCase_id = HTML.testCase_id - check_options = '' if self.ranAllowMerge: check_options = f'--build-arg MERGE_REQUEST=true --build-arg SRC_BRANCH={self.ranBranch}' diff --git a/ci-scripts/conf_files/gnb-cucp.sa.e1-ho-n2.conf b/ci-scripts/conf_files/gnb-cucp.sa.e1-ho-n2.conf index ad4cca969e..3ee84d0b85 100644 --- a/ci-scripts/conf_files/gnb-cucp.sa.e1-ho-n2.conf +++ b/ci-scripts/conf_files/gnb-cucp.sa.e1-ho-n2.conf @@ -21,10 +21,10 @@ gNBs = tr_s_preference = "f1"; - local_s_address = "192.168.71.150"; + local_s_address = "192.168.71.150"; remote_s_address = "192.168.71.171"; - local_s_portd = 2153; - remote_s_portd = 2153; + local_s_portd = 2153; + remote_s_portd = 2153; # ------- SCTP definitions SCTP : @@ -41,7 +41,7 @@ gNBs = E1_INTERFACE = ( { - type = "cp"; + type = "cp"; ipv4_cucp = "192.168.71.150"; port_cucp = 38462; ipv4_cuup = "0.0.0.0"; # multiple CU-UPs @@ -75,8 +75,8 @@ security = { log_config : { global_log_level = "info"; - pdcp_log_level = "info"; - rrc_log_level = "info"; - f1ap_log_level = "info"; - ngap_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; + f1ap_log_level = "info"; + ngap_log_level = "info"; }; diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf index 4daf7c62fd..e314a1f299 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf @@ -146,7 +146,11 @@ gNBs = ); first_active_bwp = 1; - bwp_list = ({ scs = 1; bwpStart = 0; bwpSize = 106;}); + bwp_list = ( + { scs = 1; bwpStart = 0; bwpSize = 106;}, + { scs = 1; bwpStart = 0; bwpSize = 36;}, + { scs = 1; bwpStart = 40; bwpSize = 50;} + ); # ------- SCTP definitions SCTP : diff --git a/ci-scripts/conf_files/gnb-vnf.sa.band66.u0.25prb.nfapi.conf b/ci-scripts/conf_files/gnb-vnf.sa.band66.u0.25prb.nfapi.conf index c14759c6af..6f914cf17a 100644 --- a/ci-scripts/conf_files/gnb-vnf.sa.band66.u0.25prb.nfapi.conf +++ b/ci-scripts/conf_files/gnb-vnf.sa.band66.u0.25prb.nfapi.conf @@ -16,8 +16,6 @@ gNBs = nr_cellid = 12345678L; ////////// Physical parameters: - - sib1_tda = 5; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.sa.band261.u3.32prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band261.u3.32prb.rfsim.conf index 6471c7bd02..c37acc89f5 100644 --- a/ci-scripts/conf_files/gnb.sa.band261.u3.32prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band261.u3.32prb.rfsim.conf @@ -18,8 +18,6 @@ gNBs = tr_s_preference = "local_mac" ////////// Physical parameters: - - sib1_tda = 15; min_rxtxtime = 6; servingCellConfigCommon = ( @@ -172,7 +170,7 @@ MACRLCs = ({ tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; - set_analog_beamforming = 1; + set_analog_beamforming = 2; beam_duration = 1; beams_per_period = 1; beam_weights = [0]; // single SSB -> one analog beam diff --git a/ci-scripts/conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf b/ci-scripts/conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf index 577e23a87d..3966cebc6b 100644 --- a/ci-scripts/conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf +++ b/ci-scripts/conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf @@ -30,26 +30,26 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL # this is 3610.56 MHz - absoluteFrequencySSB = 679104; - dl_frequencyBand = 77; + absoluteFrequencySSB = 679104; + dl_frequencyBand = 77; # this is 3599.94 MHz - dl_absoluteFrequencyPointA = 678388; + dl_absoluteFrequencyPointA = 678388; #scs-SpecificCarrierList - dl_offstToCarrier = 0; + dl_offstToCarrier = 0; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_subcarrierSpacing = 1; - dl_carrierBandwidth = 51; + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 51; #initialDownlinkBWP #genericParameters # this is RBstart=27,L=48 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 13750; + initialDLBWPlocationAndBandwidth = 13750; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - initialDLBWPsubcarrierSpacing = 1; + initialDLBWPsubcarrierSpacing = 1; #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 12; - initialDLBWPsearchSpaceZero = 0; + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; #uplinkConfigCommon #frequencyInfoUL @@ -197,10 +197,10 @@ RUs = ( att_rx = 0; bands = [77]; max_pdschReferenceSignalPower = -27; - max_rxgain = 114; + max_rxgain = 114; eNB_instances = [0]; - clock_src = "external"; - time_src = "external"; + clock_src = "external"; + time_src = "external"; } ); diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.vrtsim.2x2.yaml b/ci-scripts/conf_files/gnb.sa.band78.106prb.vrtsim.2x2.yaml new file mode 100644 index 0000000000..5cca2b0718 --- /dev/null +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.vrtsim.2x2.yaml @@ -0,0 +1,209 @@ +Active_gNBs: + - gnb-rfsim +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity: none +gNBs: + ##### Identification parameters: + - gNB_ID: 0xe00 + gNB_name: gnb-rfsim + tracking_area_code: 1 + plmn_list: + - mcc: 208 + mnc: 99 + mnc_length: 2 + snssaiList: + - sst: 1 + sd: 0xffffff + nr_cellid: 12345678 + ##### Physical parameters: + min_rxtxtime: 6 + pusch_AntennaPorts: 2 + pdsch_AntennaPorts_XP: 2 + + servingCellConfigCommon: + #spCellConfigCommon + - physCellId: 0 + # downlinkConfigCommon + #frequencyInfoDL + # this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68 + absoluteFrequencySSB: 621312 + # this is 3300.60 MHz + dl_absoluteFrequencyPointA: 620040 + #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=106 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth: 28875 + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing: 1 + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero: 11 + initialDLBWPsearchSpaceZero: 0 + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand: 78 + #scs-SpecificCarrierList + ul_offstToCarrier: 0 + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing: 1 + ul_carrierBandwidth: 106 + pMax: 20 + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth: 28875 + # 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: 12 + preambleReceivedTargetPower: -104 + #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 + #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 + #one (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 + 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_PositionsInBurst_Bitmap: 1 + # ssb_periodicityServingCell + # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell: 2 + + # dmrs_TypeA_position + # 0 = pos2, 1 = pos3 + dmrs_TypeA_Position: 0 + + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing: 1 + + #tdd-UL-DL-ConfigurationCommon + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing: 1 + + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity: 6 + nrofDownlinkSlots: 7 + nrofDownlinkSymbols: 6 + nrofUplinkSlots: 2 + nrofUplinkSymbols: 4 + ssPBCH_BlockPower: -25 + SCTP: + SCTP_INSTREAMS: 2 + SCTP_OUTSTREAMS: 2 + + ##### AMF parameters: + amf_ip_address: + - ipv4: 192.168.71.132 + + NETWORK_INTERFACES: + GNB_IPV4_ADDRESS_FOR_NG_AMF: 192.168.71.140 + GNB_IPV4_ADDRESS_FOR_NGU: 192.168.71.140 + GNB_PORT_FOR_S1U: 2152 # Spec 2152 + + +MACRLCs: + - num_cc: 1 + tr_s_preference: local_L1 + tr_n_preference: local_RRC + pusch_TargetSNRx10: 200 + pucch_TargetSNRx10: 200 + +L1s: + - num_cc: 1 + tr_n_preference: local_mac + prach_dtx_threshold: 200 + # pucch0_dtx_threshold = 150; + +RUs: + - local_rf: yes + nb_tx: 2 + nb_rx: 2 + att_tx: 0 + att_rx: 0 + bands: [78] + max_pdschReferenceSignalPower: -27 + max_rxgain: 75 + eNB_instances: [0] + sf_extension: 0 + +security: + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms: [nea0] + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms: [nia2, nia0] + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering: yes + drb_integrity: no + +log_config: + global_log_level: info + hw_log_level: info + phy_log_level: info + mac_log_level: info + rlc_log_level: info + pdcp_log_level: info + rrc_log_level: info + ngap_log_level: debug + f1ap_log_level: debug + + +channelmod: + max_chan: 10 + modellist: DefaultChannelList + DefaultChannelList: + - model_name: server_tx_channel_model + type: AWGN + ploss_dB: 0 + noise_power_dB: -100 + forgetfact: 0 + offset: 0 + ds_tdl: 0 diff --git a/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf index afe40c733c..7153c90421 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf @@ -16,8 +16,6 @@ gNBs = nr_cellid = 12345678L; ////////// Physical parameters: - - sib1_tda = 15; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf b/ci-scripts/conf_files/gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf index 8d6a0e90cd..ee2930f8ad 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf @@ -23,7 +23,6 @@ gNBs = pusch_AntennaPorts = 4; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; # force_UL256qam_off = 1; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/neighbour-config-ho.conf b/ci-scripts/conf_files/neighbour-config-ho.conf index 2490ce1883..07d58e14e5 100644 --- a/ci-scripts/conf_files/neighbour-config-ho.conf +++ b/ci-scripts/conf_files/neighbour-config-ho.conf @@ -42,13 +42,13 @@ nr_measurement_configuration = { A2 = { enable = 1; threshold = 110; - timeToTrigger = 1; + time_to_trigger = 1; }; A3 = ({ - cell_id = -1; #Default + physCellId = -1; #Default offset = 10; hysteresis = 0; - timeToTrigger = 1 + time_to_trigger = 1 }) }; diff --git a/ci-scripts/conf_files/neighbour-config.conf b/ci-scripts/conf_files/neighbour-config.conf index a498dbf157..9a05f01486 100644 --- a/ci-scripts/conf_files/neighbour-config.conf +++ b/ci-scripts/conf_files/neighbour-config.conf @@ -57,19 +57,19 @@ nr_measurement_configuration = { A2 = { enable = 1; threshold = 60; - timeToTrigger = 1; + time_to_trigger = 1; }; A3 = ({ physCellId = -1; #Default offset = 10; hysteresis = 0; - timeToTrigger = 1 + time_to_trigger = 1 }, { physCellId = 2; offset = 5; hysteresis = 1; - timeToTrigger = 2 + time_to_trigger = 2 }) }; diff --git a/ci-scripts/conf_files/nrue.vrtsim.chanmod.yaml b/ci-scripts/conf_files/nrue.vrtsim.chanmod.yaml new file mode 100644 index 0000000000..a9488007d7 --- /dev/null +++ b/ci-scripts/conf_files/nrue.vrtsim.chanmod.yaml @@ -0,0 +1,20 @@ +uicc0: + imsi: 208990100001100 + key: fec86ba6eb707ed08905757b1bb44b8f + opc: C42449363BBAD02B66D16BC975D77CC1 + dnn: oai + nssai_sst: 1 + +thread-pool: "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" + +channelmod: + max_chan: 10; + modellist: DefaultChannelList + DefaultChannelList: + - model_name: client_tx_channel_model + type: AWGN + ploss_dB: 0 + noise_power_dB: -100 + forgetfact: 0 + offset: 0 + ds_tdl: 0 diff --git a/ci-scripts/docker/Dockerfile.physim.ubuntu b/ci-scripts/docker/Dockerfile.physim.ubuntu index 8fe6d91c4a..c820c7fd7a 100644 --- a/ci-scripts/docker/Dockerfile.physim.ubuntu +++ b/ci-scripts/docker/Dockerfile.physim.ubuntu @@ -44,4 +44,4 @@ RUN cmake -GNinja -DENABLE_PHYSIM_TESTS=ON \ -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror \ -DPHYSIM_CHECK_FILES="ThresholdsGracehopper.cmake" \ .. && \ - ninja ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim + ninja ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim nr_srssim diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 8aadad76bb..1995ff545b 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -58,7 +58,7 @@ import re # reg import time # sleep import os import subprocess -import xml.etree.ElementTree as ET +import lxml.etree as ET import logging import signal import traceback @@ -98,7 +98,7 @@ def ExecuteActionWithParam(action, ctx, node): if proxy_commit is not None: CONTAINERS.proxyCommit = proxy_commit if action == 'Build_eNB': - success = cls_native.Native.Build(ctx, node, HTML.testCase_id, HTML, RAN.eNBSourceCodePath, RAN.Build_eNB_args) + success = cls_native.Native.Build(ctx, node, HTML, RAN.eNBSourceCodePath, RAN.Build_eNB_args) elif action == 'Build_Image': success = CONTAINERS.BuildImage(ctx, node, HTML) elif action == 'Build_Proxy': @@ -306,10 +306,10 @@ def receive_signal(signum, frame): logging.warning("received signal again, exiting") sys.exit(1) -def ShowTestID(ctx, desc): +def ShowTestID(ctx, desc, file, line): logging.info(f'\u001B[1m----------------------------------------\u001B[0m') - logging.info(f'\u001B[1m Test ID: {ctx.test_id} (#{ctx.count}) \u001B[0m') - logging.info(f'\u001B[1m {desc} \u001B[0m') + logging.info(f'\u001B[1m Test #{ctx.test_idx} ({file}:{line}) \u001B[0m') + logging.info(f'\u001B[1m {desc} \u001B[0m') logging.info(f'\u001B[1m----------------------------------------\u001B[0m') #----------------------------------------------------------- @@ -455,46 +455,11 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re xmlTree = ET.parse(xml_test_file) xmlRoot = xmlTree.getroot() - exclusion_tests=xmlRoot.findtext('TestCaseExclusionList',default='') - requested_tests=xmlRoot.findtext('TestCaseRequestedList',default='') if (HTML.nbTestXMLfiles == 1): HTML.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) HTML.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0')) all_tests=xmlRoot.findall('testCase') - exclusion_tests=exclusion_tests.split() - requested_tests=requested_tests.split() - - #check that exclusion tests are well formatted - #(6 digits or less than 6 digits followed by +) - for test in exclusion_tests: - if (not re.match('^[0-9]{6}$', test) and - not re.match('^[0-9]{1,5}\\+$', test)): - logging.error('exclusion test is invalidly formatted: ' + test) - sys.exit(1) - else: - logging.info(test) - - #check that requested tests are well formatted - #(6 digits or less than 6 digits followed by +) - #be verbose - for test in requested_tests: - if (re.match('^[0-9]{6}$', test) or - re.match('^[0-9]{1,5}\\+$', test)): - logging.info('test group/case requested: ' + test) - else: - logging.error('requested test is invalidly formatted: ' + test) - sys.exit(1) - - #get the list of tests to be done - todo_tests=[] - for test in requested_tests: - if (test_in_list(test, exclusion_tests)): - logging.info('test will be skipped: ' + test) - else: - #logging.info('test will be run: ' + test) - todo_tests.append(test) - signal.signal(signal.SIGINT, receive_signal) HTML.CreateHtmlTabHeader() @@ -502,46 +467,42 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re task_set_succeeded = True HTML.startTime=int(round(time.time() * 1000)) - i = 0 - for test_case_id in todo_tests: - for test in all_tests: - if test_runner_abort: + for index, test in enumerate(all_tests, start=1): + if test_runner_abort: + task_set_succeeded = False + test_case_idx = f"{index:06d}" + ctx = TestCaseCtx(int(test_case_idx), logPath) + HTML.testCaseIdx = test_case_idx + desc = test.findtext('desc') + node = test.findtext('node') if not force_local else 'localhost' + always_exec = test.findtext('always_exec') in ['True', 'true', 'Yes', 'yes'] + may_fail = test.findtext('may_fail') in ['True', 'true', 'Yes', 'yes'] + HTML.desc = desc + action = test.findtext('class') + if not CheckClassValidity(xml_class_list, action, test_case_idx): + task_set_succeeded = False + continue + file = os.path.basename(xml_test_file) + line = test.find('class').sourceline + ShowTestID(ctx, desc, file, line) + if not task_set_succeeded and not always_exec: + msg = f"skipping test due to prior error" + logging.warning(msg) + HTML.CreateHtmlTestRowQueue(msg, "SKIP", []) + continue + try: + test_succeeded = ExecuteActionWithParam(action, ctx, node) + if not test_succeeded and may_fail: + logging.warning(f"test ID {test_case_idx} action {action} may or may not fail, proceeding despite error") + elif not test_succeeded: + logging.error(f"test ID {test_case_idx} action {action} failed ({test_succeeded}), skipping next tests") task_set_succeeded = False - id = test.get('id') - if test_case_id != id: - continue - i += 1 - CiTestObj.testCase_id = id - ctx = TestCaseCtx(i, int(id), logPath) - HTML.testCase_id=CiTestObj.testCase_id - desc = test.findtext('desc') - node = test.findtext('node') if not force_local else 'localhost' - always_exec = test.findtext('always_exec') in ['True', 'true', 'Yes', 'yes'] - may_fail = test.findtext('may_fail') in ['True', 'true', 'Yes', 'yes'] - HTML.desc = desc - action = test.findtext('class') - if (CheckClassValidity(xml_class_list, action, id) == False): - task_set_succeeded = False - continue - ShowTestID(ctx, desc) - if not task_set_succeeded and not always_exec: - msg = f"skipping test due to prior error" - logging.warning(msg) - HTML.CreateHtmlTestRowQueue(msg, "SKIP", []) - break - try: - test_succeeded = ExecuteActionWithParam(action, ctx, node) - if not test_succeeded and may_fail: - logging.warning(f"test ID {test_case_id} action {action} may or may not fail, proceeding despite error") - elif not test_succeeded: - logging.error(f"test ID {test_case_id} action {action} failed ({test_succeeded}), skipping next tests") - task_set_succeeded = False - except Exception as e: - s = traceback.format_exc() - logging.error(f'while running CI, an exception occurred:\n{s}') - HTML.CreateHtmlTestRowQueue("N/A", 'KO', [f"CI test code encountered an exception:\n{s}"]) - task_set_succeeded = False - break + except Exception as e: + s = traceback.format_exc() + logging.error(f'while running CI, an exception occurred:\n{s}') + HTML.CreateHtmlTestRowQueue("N/A", 'KO', [f"CI test code encountered an exception:\n{s}"]) + task_set_succeeded = False + continue if not task_set_succeeded: logging.error('\u001B[1;37;41mScenario failed\u001B[0m') diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index e440fc3a62..04384ad4f4 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -67,7 +67,6 @@ class RANManagement(): self.eNBOptions = ['', '', ''] self.eNBmbmsEnables = [False, False, False] self.eNBstatuses = [-1, -1, -1] - self.testCase_id = '' self.runtime_stats= '' self.datalog_rt_stats={} self.datalog_rt_stats_file='datalog_rt_stats.default.yaml' @@ -88,7 +87,6 @@ class RANManagement(): raise ValueError(f"{node=}") logging.debug('Starting eNB/gNB on server: ' + node) - self.testCase_id = HTML.testCase_id lSourcePath = self.eNBSourceCodePath cmd = cls_cmd.getConnection(node) diff --git a/ci-scripts/tests/build.py b/ci-scripts/tests/build.py index 013486a560..8701b17a8c 100644 --- a/ci-scripts/tests/build.py +++ b/ci-scripts/tests/build.py @@ -17,7 +17,7 @@ import cls_cmd class TestBuild(unittest.TestCase): def setUp(self): self.html = cls_oai_html.HTMLManagement() - self.html.testCase_id = "000000" + self.html.testCaseIdx = "000000" self.cont = cls_containerize.Containerize() self._d = tempfile.mkdtemp() logging.warning(f"temporary directory: {self._d}") diff --git a/ci-scripts/tests/test-runner/test.xml b/ci-scripts/tests/test-runner/test.xml index cb54989301..635ccb3b6b 100644 --- a/ci-scripts/tests/test-runner/test.xml +++ b/ci-scripts/tests/test-runner/test.xml @@ -22,60 +22,51 @@ --> - test - Manual testing - wrench - - 000001 - 000011 - 000012 - 000002 - 000003 - 000004 - - + test + Manual testing + wrench + + Custom_Command + This should succeed + localhost + true + - - Custom_Command - This should succeed - localhost - true - + + Custom_Command + This may fail + true + localhost + false + - - Custom_Command - This may fail - true - localhost - false - + + Custom_Command + This is still executed + localhost + true + - - Custom_Command - This is still executed - localhost - true - + + Custom_Command + This should fail + localhost + false + - - Custom_Command - This should fail - localhost - false - + + Custom_Command + This should be skipped + localhost + true + - - Custom_Command - This should be skipped - localhost - true - + + Custom_Command + This should be executed because marked so + true + localhost + true + - - Custom_Command - This should be executed because marked so - true - localhost - true - diff --git a/ci-scripts/xml_files/cluster_image_build.xml b/ci-scripts/xml_files/cluster_image_build.xml index a80d1cd7d4..086b6a0880 100644 --- a/ci-scripts/xml_files/cluster_image_build.xml +++ b/ci-scripts/xml_files/cluster_image_build.xml @@ -21,23 +21,20 @@ --> - build-tab - Build Images on Cluster - wrench - - 000002 - 000001 - - - - Create_Workspace - Create new Workspace - poseidon - - - Build_Cluster_Image - Build Images on OpenShift Cluster - poseidon - + build-tab + Build Images on Cluster + wrench + + + Create_Workspace + Create new Workspace + poseidon + + + + Build_Cluster_Image + Build Images on OpenShift Cluster + poseidon + diff --git a/ci-scripts/xml_files/container_4g_l2sim_tdd.xml b/ci-scripts/xml_files/container_4g_l2sim_tdd.xml index 8a010b9308..1b3ec37b81 100644 --- a/ci-scripts/xml_files/container_4g_l2sim_tdd.xml +++ b/ci-scripts/xml_files/container_4g_l2sim_tdd.xml @@ -21,136 +21,122 @@ --> - l2sim-4glte-tdd - Testing 4G LTE L2 sim - FDD eNB - wrench - - 111111 - 800813 - 000000 - 000001 - 000002 - 000003 - 000004 - 020001 - 020002 - 030011 - 030012 - 100001 - 222222 - - + l2sim-4glte-tdd + Testing 4G LTE L2 sim - FDD eNB + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-enb oai-lte-ue - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy Cassandra Database - localhost - ci-scripts/yaml_files/4g_l2sim_fdd - cassandra db_init - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-enb oai-lte-ue + - - Deploy_Object - Deploy OAI 4G CoreNetwork - localhost - ci-scripts/yaml_files/4g_l2sim_fdd - oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 4G eNB L2 sim - localhost - ci-scripts/yaml_files/4g_l2sim_fdd - oai_enb - + + Deploy_Object + Deploy Cassandra Database + localhost + ci-scripts/yaml_files/4g_l2sim_fdd + cassandra db_init + - - Deploy_Object - Deploy OAI L2 sim 4G LTE-UE 1 and Proxy - localhost - ci-scripts/yaml_files/4g_l2sim_fdd - proxy oai_ue1 - + + Deploy_Object + Deploy OAI 4G CoreNetwork + localhost + ci-scripts/yaml_files/4g_l2sim_fdd + oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen + - - Attach_UE - Attach OAI UE - l2sim4g_ue - localhost - + + Deploy_Object + Deploy OAI 4G eNB L2 sim + localhost + ci-scripts/yaml_files/4g_l2sim_fdd + oai_enb + - - Ping - Ping trf-gen from LTE-UE 1 - l2sim4g_ue - localhost - l2sim4g_ext_dn - localhost - -c 20 - 0 - + + Deploy_Object + Deploy OAI L2 sim 4G LTE-UE 1 and Proxy + localhost + ci-scripts/yaml_files/4g_l2sim_fdd + proxy oai_ue1 + - - Ping - Ping LTE-UE 1 from trf-gen - l2sim4g_ext_dn - localhost - l2sim4g_ue - localhost - -c 20 - 0 - + + Attach_UE + Attach OAI UE + l2sim4g_ue + localhost + - - Iperf - Iperf UDP Downlink - l2sim4g_ue - localhost - l2sim4g_ext_dn - localhost - -u -t 30 -b 1M -R - 25 - 80 - + + Ping + Ping trf-gen from LTE-UE 1 + l2sim4g_ue + localhost + l2sim4g_ext_dn + localhost + -c 20 + 0 + - - Iperf - Iperf UDP Uplink - l2sim4g_ue - localhost - l2sim4g_ext_dn - localhost - -u -t 30 -b 3M - 25 - 80 - + + Ping + Ping LTE-UE 1 from trf-gen + l2sim4g_ext_dn + localhost + l2sim4g_ue + localhost + -c 20 + 0 + - - Undeploy_Object - true - localhost - Undeploy all OAI 4G stack - ci-scripts/yaml_files/4g_l2sim_fdd - + + Iperf + Iperf UDP Downlink + l2sim4g_ue + localhost + l2sim4g_ext_dn + localhost + -u -t 30 -b 1M -R + 25 + 80 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-enb oai-lte-ue - + + Iperf + Iperf UDP Uplink + l2sim4g_ue + localhost + l2sim4g_ext_dn + localhost + -u -t 30 -b 3M + 25 + 80 + + + + Undeploy_Object + true + localhost + Undeploy all OAI 4G stack + ci-scripts/yaml_files/4g_l2sim_fdd + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-enb oai-lte-ue + diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml index 3606957af6..adad131ef7 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml @@ -21,151 +21,140 @@ --> - rfsim-4glte-fdd05mhz - Monolithic eNB - FDD 05MHz - wrench - - 111111 - 800813 - 000011 - 000001 - 000012 - 000002 - 000013 - 000001 - 000014 - 000015 - 020011 - 020012 - 030011 - 030012 - 100011 - 222222 - - - - Create_Workspace - Create new Workspace - localhost - - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-enb-asan oai-lte-ue-asan - + rfsim-4glte-fdd05mhz + Monolithic eNB - FDD 05MHz + wrench - - Deploy_Object - Deploy Cassandra Database - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz - cassandra db_init - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-enb-asan oai-lte-ue-asan + - - IdleSleep - Sleep - 30 - + + Create_Workspace + Create new Workspace + localhost + - - IdleSleep - Sleep - 10 - + + Deploy_Object + Deploy Cassandra Database + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz + cassandra db_init + - - Deploy_Object - Deploy OAI 4G CoreNetwork - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz - oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen - + + IdleSleep + Sleep + 30 + - - Deploy_Object - Deploy OAI 4G eNB RF sim (FDD 05MHz) - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz - oai_enb0 - + + Deploy_Object + Deploy OAI 4G CoreNetwork + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz + oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen + - - Deploy_Object - Deploy OAI 4G LTE-UE RF sim (FDD 05MHz) - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz - oai_ue0 - + + IdleSleep + Sleep + 10 + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim4g_ue - localhost - + + Deploy_Object + Deploy OAI 4G eNB RF sim (FDD 05MHz) + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz + oai_enb0 + - - Ping - Ping Traffic-Gen from LTE-UE - rfsim4g_ue - localhost - rfsim4g_ext_dn - localhost - -c 20 - 5 - + + IdleSleep + Sleep + 30 + - - Ping - Ping LTE-UE from Traffic-Gen - rfsim4g_ext_dn - localhost - rfsim4g_ue - localhost - -c 20 - 5 - + + Deploy_Object + Deploy OAI 4G LTE-UE RF sim (FDD 05MHz) + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz + oai_ue0 + - - Iperf - Iperf UDP DL - rfsim4g_ue - rfsim4g_ext_dn - -u -t 30 -b 2M -R - 25 - 80 - localhost - localhost - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim4g_ue + localhost + - - Iperf - Iperf UDP UL - rfsim4g_ue - rfsim4g_ext_dn - -u -t 30 -b 1M - 25 - 80 - localhost - localhost - + + Ping + Ping Traffic-Gen from LTE-UE + rfsim4g_ue + localhost + rfsim4g_ext_dn + localhost + -c 20 + 5 + - - Undeploy_Object - true - Undeploy all OAI 4G stack - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz - + + Ping + Ping LTE-UE from Traffic-Gen + rfsim4g_ext_dn + localhost + rfsim4g_ue + localhost + -c 20 + 5 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-enb-asan oai-lte-ue-asan - + + Iperf + Iperf UDP UL + rfsim4g_ue + rfsim4g_ext_dn + -u -t 30 -b 1M + 25 + 80 + localhost + localhost + + + + Iperf + Iperf UDP DL + rfsim4g_ue + rfsim4g_ext_dn + -u -t 30 -b 2M -R + 25 + 80 + localhost + localhost + + + + Undeploy_Object + true + Undeploy all OAI 4G stack + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-enb-asan oai-lte-ue-asan + diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml index 1d7194f44f..0879e27170 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml @@ -21,124 +21,111 @@ --> - rfsim-4glte-fdd05mhz-noS1 - Monolithic eNB - FDD 05MHz - noS1 - wrench - - 111111 -800813 - 000013 - 000002 - 000014 - 000001 - 020011 - 020012 - 030011 - 030012 - 100011 - 222222 - - + rfsim-4glte-fdd05mhz-noS1 + Monolithic eNB - FDD 05MHz - noS1 + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-enb-asan oai-lte-ue-asan - - - Create_Workspace - Create new Workspace - localhost - - - IdleSleep - Sleep - 30 - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-enb-asan oai-lte-ue-asan + - - IdleSleep - Sleep - 10 - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 4G eNB RF sim (FDD 05MHz) - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1 - oai_enb0 - + + Deploy_Object + Deploy OAI 4G eNB RF sim (FDD 05MHz) + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1 + oai_enb0 + - - Deploy_Object - Deploy OAI 4G LTE-UE RF sim (FDD 05MHz) - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1 - oai_ue0 - + + IdleSleep + Sleep + 10 + - - Ping - Ping Traffic-Gen from LTE-UE - rfsim4g_ue - localhost - rfsim4g_enb_nos1 - localhost - -c 20 - 5 - + + Deploy_Object + Deploy OAI 4G LTE-UE RF sim (FDD 05MHz) + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1 + oai_ue0 + - - Ping - Ping LTE-UE from eNB - rfsim4g_enb_nos1 - localhost - rfsim4g_ue - localhost - -c 20 - 5 - + + IdleSleep + Sleep + 30 + - - Iperf - Iperf UDP DL - rfsim4g_ue - localhost - rfsim4g_enb_nos1 - localhost - -u -t 30 -b 2M -R - 25 - 80 - + + Ping + Ping Traffic-Gen from LTE-UE + rfsim4g_ue + localhost + rfsim4g_enb_nos1 + localhost + -c 20 + 5 + - - Iperf - Iperf UDP UL - rfsim4g_ue - localhost - rfsim4g_enb_nos1 - localhost - -u -t 30 -b 1M - 25 - 80 - + + Ping + Ping LTE-UE from eNB + rfsim4g_enb_nos1 + localhost + rfsim4g_ue + localhost + -c 20 + 5 + - - Undeploy_Object - true - Undeploy all OAI 4G stack - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1 - + + Iperf + Iperf UDP DL + rfsim4g_ue + localhost + rfsim4g_enb_nos1 + localhost + -u -t 30 -b 2M -R + 25 + 80 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-enb-asan oai-lte-ue-asan - + + Iperf + Iperf UDP UL + rfsim4g_ue + localhost + rfsim4g_enb_nos1 + localhost + -u -t 30 -b 1M + 25 + 80 + + + + Undeploy_Object + true + Undeploy all OAI 4G stack + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-enb-asan oai-lte-ue-asan + diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml index a5b642ebe0..acde953fe8 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml @@ -21,151 +21,140 @@ --> - rfsim-4glte-fdd10mhz - Monolithic eNB - FDD 10MHz - wrench - - 111111 - 800813 - 000011 - 000001 - 000012 - 000002 - 000013 - 000001 - 000014 - 000015 - 020011 - 020012 - 030011 - 030012 - 100011 - 222222 - - + rfsim-4glte-fdd10mhz + Monolithic eNB - FDD 10MHz + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-enb-asan oai-lte-ue-asan - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy Cassandra Database - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz - cassandra db_init - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-enb-asan oai-lte-ue-asan + - - IdleSleep - Sleep - 30 - + + Create_Workspace + Create new Workspace + localhost + - - IdleSleep - Sleep - 10 - + + Deploy_Object + Deploy Cassandra Database + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz + cassandra db_init + - - Deploy_Object - Deploy OAI 4G CoreNetwork - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz - oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen - + + IdleSleep + Sleep + 30 + - - Deploy_Object - Deploy OAI 4G eNB RF sim (FDD 10MHz) - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz - oai_enb0 - + + Deploy_Object + Deploy OAI 4G CoreNetwork + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz + oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen + - - Deploy_Object - Deploy OAI 4G LTE-UE RF sim (FDD 10MHz) - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz - oai_ue0 - + + IdleSleep + Sleep + 10 + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim4g_ue - localhost - + + Deploy_Object + Deploy OAI 4G eNB RF sim (FDD 10MHz) + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz + oai_enb0 + - - Ping - Ping Traffic-Gen from LTE-UE - rfsim4g_ue - localhost - rfsim4g_ext_dn - localhost - -c 20 - 5 - + + IdleSleep + Sleep + 30 + - - Ping - Ping LTE-UE from Traffic-Gen - rfsim4g_ext_dn - localhost - rfsim4g_ue - localhost - -c 20 - 5 - + + Deploy_Object + Deploy OAI 4G LTE-UE RF sim (FDD 10MHz) + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz + oai_ue0 + - - Iperf - Iperf UDP DL - rfsim4g_ue - localhost - rfsim4g_ext_dn - localhost - -u -t 30 -b 2M -R - 25 - 80 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim4g_ue + localhost + - - Iperf - Iperf UDP UL - rfsim4g_ue - localhost - rfsim4g_ext_dn - localhost - -u -t 30 -b 1M - 25 - 80 - + + Ping + Ping Traffic-Gen from LTE-UE + rfsim4g_ue + localhost + rfsim4g_ext_dn + localhost + -c 20 + 5 + - - Undeploy_Object - true - Undeploy all OAI 4G stack - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz - + + Ping + Ping LTE-UE from Traffic-Gen + rfsim4g_ext_dn + localhost + rfsim4g_ue + localhost + -c 20 + 5 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-enb-asan oai-lte-ue-asan - + + Iperf + Iperf UDP DL + rfsim4g_ue + localhost + rfsim4g_ext_dn + localhost + -u -t 30 -b 2M -R + 25 + 80 + + + + Iperf + Iperf UDP UL + rfsim4g_ue + localhost + rfsim4g_ext_dn + localhost + -u -t 30 -b 1M + 25 + 80 + + + + Undeploy_Object + true + Undeploy all OAI 4G stack + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-enb-asan oai-lte-ue-asan + diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml index 592c80de68..cf6eb1d838 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml @@ -21,151 +21,140 @@ --> - rfsim-4glte-fdd20mhz - Monolithic eNB - FDD 20MHz - wrench - - 111111 - 800813 - 000011 - 000001 - 000012 - 000002 - 000013 - 000001 - 000014 - 000015 - 020011 - 020012 - 030011 - 030012 - 100011 - 222222 - - + rfsim-4glte-fdd20mhz + Monolithic eNB - FDD 20MHz + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-enb-asan oai-lte-ue-asan - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy Cassandra Database - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz - cassandra db_init - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-enb-asan oai-lte-ue-asan + - - IdleSleep - Sleep - 30 - + + Create_Workspace + Create new Workspace + localhost + - - IdleSleep - Sleep - 10 - + + Deploy_Object + Deploy Cassandra Database + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz + cassandra db_init + - - Deploy_Object - Deploy OAI 4G CoreNetwork - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz - oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen - + + IdleSleep + Sleep + 30 + - - Deploy_Object - Deploy OAI 4G eNB RF sim (FDD 20MHz) - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz - oai_enb0 - + + Deploy_Object + Deploy OAI 4G CoreNetwork + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz + oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen + - - Deploy_Object - Deploy OAI 4G LTE-UE RF sim (FDD 20MHz) - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz - oai_ue0 - + + IdleSleep + Sleep + 10 + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim4g_ue - localhost - + + Deploy_Object + Deploy OAI 4G eNB RF sim (FDD 20MHz) + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz + oai_enb0 + - - Ping - Ping Traffic-Gen from LTE-UE - rfsim4g_ue - localhost - rfsim4g_ext_dn - localhost - -c 20 - 5 - + + IdleSleep + Sleep + 30 + - - Ping - Ping LTE-UE from Traffic-Gen - rfsim4g_ext_dn - localhost - rfsim4g_ue - localhost - -c 20 - 5 - + + Deploy_Object + Deploy OAI 4G LTE-UE RF sim (FDD 20MHz) + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz + oai_ue0 + - - Iperf - Iperf UDP DL - rfsim4g_ue - localhost - rfsim4g_ext_dn - localhost - -u -t 30 -b 2M -R - 25 - 80 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim4g_ue + localhost + - - Iperf - Iperf UDP UL - rfsim4g_ue - localhost - rfsim4g_ext_dn - localhost - -u -t 30 -b 1M - 25 - 80 - + + Ping + Ping Traffic-Gen from LTE-UE + rfsim4g_ue + localhost + rfsim4g_ext_dn + localhost + -c 20 + 5 + - - Undeploy_Object - true - Undeploy all OAI 4G stack - localhost - ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz - + + Ping + Ping LTE-UE from Traffic-Gen + rfsim4g_ext_dn + localhost + rfsim4g_ue + localhost + -c 20 + 5 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-enb-asan oai-lte-ue-asan - + + Iperf + Iperf UDP DL + rfsim4g_ue + localhost + rfsim4g_ext_dn + localhost + -u -t 30 -b 2M -R + 25 + 80 + + + + Iperf + Iperf UDP UL + rfsim4g_ue + localhost + rfsim4g_ext_dn + localhost + -u -t 30 -b 1M + 25 + 80 + + + + Undeploy_Object + true + Undeploy all OAI 4G stack + localhost + ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-enb-asan oai-lte-ue-asan + diff --git a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml index 21d2acc4eb..f03fb12e76 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml @@ -21,87 +21,77 @@ --> - rfsim-4glte-fembms - Monolithic eNB - FeMBMS - wrench - - 111111 - 800813 - 000013 - 000002 - 000014 - 000001 - 030011 - 100011 - 222222 - - + rfsim-4glte-fembms + Monolithic eNB - FeMBMS + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-enb-asan oai-lte-ue-asan - - - Create_Workspace - Create new Workspace - localhost - - - IdleSleep - Sleep - 30 - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-enb-asan oai-lte-ue-asan + - - IdleSleep - Sleep - 10 - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 4G eNB RF sim (FeMBMS) - localhost - ci-scripts/yaml_files/4g_rfsimulator_fembms - oai_enb0 - + + Deploy_Object + Deploy OAI 4G eNB RF sim (FeMBMS) + localhost + ci-scripts/yaml_files/4g_rfsimulator_fembms + oai_enb0 + - - Deploy_Object - Deploy OAI 4G LTE-UE RF sim (FeMBMS) - localhost - ci-scripts/yaml_files/4g_rfsimulator_fembms - oai_ue0 - + + IdleSleep + Sleep + 10 + - - Iperf2_Unidir - Iperf2 UDP DL - rfsim4g_ue_fembms - localhost - rfsim4g_enb_fembms - localhost - -u -t 30 -b 2M - 25 - 80 - + + Deploy_Object + Deploy OAI 4G LTE-UE RF sim (FeMBMS) + localhost + ci-scripts/yaml_files/4g_rfsimulator_fembms + oai_ue0 + - - Undeploy_Object - true - Undeploy all OAI 4G stack - localhost - ci-scripts/yaml_files/4g_rfsimulator_fembms - + + IdleSleep + Sleep + 30 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-enb-asan oai-lte-ue-asan - + + Iperf2_Unidir + Iperf2 UDP DL + rfsim4g_ue_fembms + localhost + rfsim4g_enb_fembms + localhost + -u -t 30 -b 2M + 25 + 80 + + + + Undeploy_Object + true + Undeploy all OAI 4G stack + localhost + ci-scripts/yaml_files/4g_rfsimulator_fembms + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-enb-asan oai-lte-ue-asan + diff --git a/ci-scripts/xml_files/container_4g_rfsim_mbms.xml b/ci-scripts/xml_files/container_4g_rfsim_mbms.xml index 70d5db33cb..f41aa98a9f 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_mbms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_mbms.xml @@ -21,87 +21,77 @@ --> - rfsim-4glte-mbms - Monolithic eNB - MBMS - wrench - - 111111 - 800813 - 000013 - 000002 - 000014 - 000001 - 030011 - 100011 - 222222 - - + rfsim-4glte-mbms + Monolithic eNB - MBMS + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-enb-asan oai-lte-ue-asan - - - Create_Workspace - Create new Workspace - localhost - - - IdleSleep - Sleep - 30 - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-enb-asan oai-lte-ue-asan + - - IdleSleep - Sleep - 10 - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 4G eNB RF sim (MBMS) - localhost - ci-scripts/yaml_files/4g_rfsimulator_mbms - oai_enb0 - + + Deploy_Object + Deploy OAI 4G eNB RF sim (MBMS) + localhost + ci-scripts/yaml_files/4g_rfsimulator_mbms + oai_enb0 + - - Deploy_Object - Deploy OAI 4G LTE-UE RF sim (MBMS) - localhost - ci-scripts/yaml_files/4g_rfsimulator_mbms - oai_ue0 - + + IdleSleep + Sleep + 10 + - - Iperf - Iperf UDP DL - rfsim4g_ue - localhost - rfsim4g_enb_nos1 - localhost - -u -t 30 -b 2M -R - 25 - 80 - + + Deploy_Object + Deploy OAI 4G LTE-UE RF sim (MBMS) + localhost + ci-scripts/yaml_files/4g_rfsimulator_mbms + oai_ue0 + - - Undeploy_Object - true - Undeploy all OAI 4G stack - localhost - ci-scripts/yaml_files/4g_rfsimulator_mbms - + + IdleSleep + Sleep + 30 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-enb-asan oai-lte-ue-asan - + + Iperf + Iperf UDP DL + rfsim4g_ue + localhost + rfsim4g_enb_nos1 + localhost + -u -t 30 -b 2M -R + 25 + 80 + + + + Undeploy_Object + true + Undeploy all OAI 4G stack + localhost + ci-scripts/yaml_files/4g_rfsimulator_mbms + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-enb-asan oai-lte-ue-asan + diff --git a/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml index 60054cb305..f57ff9eb14 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml @@ -21,144 +21,139 @@ --> - rfsim-4glte-tdd05mhz - Monolithic eNB - TDD 05MHz - wrench - - 111111 - 800813 - 000011 - 000001 - 000012 - 000002 - 000013 - 000001 - 000014 - 000002 - 020011 - 020012 - 030011 - 030012 - 100011 - 222222 - - + rfsim-4glte-tdd05mhz + Monolithic eNB - TDD 05MHz + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-enb oai-lte-ue - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy Cassandra Database - localhost - ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz - cassandra db_init - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-enb oai-lte-ue + - - IdleSleep - Sleep - 30 - + + Create_Workspace + Create new Workspace + localhost + - - IdleSleep - Sleep - 10 - + + Deploy_Object + Deploy Cassandra Database + localhost + ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz + cassandra db_init + - - Deploy_Object - Deploy OAI 4G CoreNetwork - localhost - ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz - oai_hss oai_mme oai_spgwc oai_spgwu trf_gen - + + IdleSleep + Sleep + 30 + - - Deploy_Object - Deploy OAI 4G eNB RF sim (TDD 05MHz) - localhost - ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz - oai_enb0 - + + Deploy_Object + Deploy OAI 4G CoreNetwork + localhost + ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz + oai_hss oai_mme oai_spgwc oai_spgwu trf_gen + - - Deploy_Object - Deploy OAI 4G LTE-UE RF sim (TDD 05MHz) - localhost - ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz - oai_ue0 - + + IdleSleep + Sleep + 10 + - - Ping - Ping Traffic-Gen from LTE-UE - rfsim4g_ue - localhost - rfsim4g_ext_dn - localhost - -c 20 - 5 - + + Deploy_Object + Deploy OAI 4G eNB RF sim (TDD 05MHz) + localhost + ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz + oai_enb0 + - - Ping - Ping LTE-UE from Traffic-Gen - rfsim4g_ext_dn - localhost - rfsim4g_ue - localhost - -c 20 - 5 - + + IdleSleep + Sleep + 30 + - - Iperf - Iperf UDP DL - rfsim4g_ue - localhost - rfsim4g_ext_dn - localhost - -u -t 30 -b 2M -R - 25 - 80 - + + Deploy_Object + Deploy OAI 4G LTE-UE RF sim (TDD 05MHz) + localhost + ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz + oai_ue0 + - - Iperf - Iperf UDP UL - rfsim4g_ue - localhost - rfsim4g_ext_dn - localhost - -u -t 30 -b 1M - 25 - 80 - + + IdleSleep + Sleep + 10 + - - Undeploy_Object - true - Undeploy all OAI 4G stack - localhost - ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz - + + Ping + Ping Traffic-Gen from LTE-UE + rfsim4g_ue + localhost + rfsim4g_ext_dn + localhost + -c 20 + 5 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-enb oai-lte-ue - + + Ping + Ping LTE-UE from Traffic-Gen + rfsim4g_ext_dn + localhost + rfsim4g_ue + localhost + -c 20 + 5 + + + + Iperf + Iperf UDP DL + rfsim4g_ue + localhost + rfsim4g_ext_dn + localhost + -u -t 30 -b 2M -R + 25 + 80 + + + + Iperf + Iperf UDP UL + rfsim4g_ue + localhost + rfsim4g_ext_dn + localhost + -u -t 30 -b 1M + 25 + 80 + + + + Undeploy_Object + true + Undeploy all OAI 4G stack + localhost + ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-enb oai-lte-ue + diff --git a/ci-scripts/xml_files/container_5g_e1_rfsim.xml b/ci-scripts/xml_files/container_5g_e1_rfsim.xml index 5c0fa2b99e..fc3be58e2d 100644 --- a/ci-scripts/xml_files/container_5g_e1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_e1_rfsim.xml @@ -21,91 +21,81 @@ --> - rfsim-5gnr-e1 - CUCP-CUUP-DU E1+F1 split - wrench - - 111111 - 800813 - 000021 - 000022 - 000023 - 000024 - 020021 - 100021 - 222222 - - + rfsim-5gnr-e1 + CUCP-CUUP-DU E1+F1 split + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb oai-nr-cuup oai-nr-ue - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_rfsimulator_e1 - mysql oai-amf oai-smf oai-upf - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb oai-nr-cuup oai-nr-ue + - - Deploy_Object - Deploy OAI 5G RAN RF sim SA (1 CU-CP, 3 CU-UPs, 3 DUs) - localhost - ci-scripts/yaml_files/5g_rfsimulator_e1 - oai-cucp oai-cuup oai-cuup2 oai-cuup3 oai-du oai-du2 oai-du3 - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 5G NR-UE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_e1 - oai-nr-ue oai-nr-ue2 oai-nr-ue3 - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_rfsimulator_e1 + mysql oai-amf oai-smf oai-upf + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 - localhost - + + Deploy_Object + Deploy OAI 5G RAN RF sim SA (1 CU-CP, 3 CU-UPs, 3 DUs) + localhost + ci-scripts/yaml_files/5g_rfsimulator_e1 + oai-cucp oai-cuup oai-cuup2 oai-cuup3 oai-du oai-du2 oai-du3 + - - Ping - Ping ext-dn from all NR-UEs - rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 - localhost - rfsim5g_5gc_fixed_ip - localhost - -c 20 -i0.25 - 5 - + + Deploy_Object + Deploy OAI 5G NR-UE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_e1 + oai-nr-ue oai-nr-ue2 oai-nr-ue3 + - - Undeploy_Object - true - localhost - Undeploy all OAI 5G stack - ci-scripts/yaml_files/5g_rfsimulator_e1 - 1,0,0,0 - 1,0,0,0 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 + localhost + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb oai-nr-cuup oai-nr-ue - + + Ping + Ping ext-dn from all NR-UEs + rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 + localhost + rfsim5g_5gc_fixed_ip + localhost + -c 20 -i0.25 + 5 + + + + Undeploy_Object + true + localhost + Undeploy all OAI 5G stack + ci-scripts/yaml_files/5g_rfsimulator_e1 + 1,0,0,0 + 1,0,0,0 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb oai-nr-cuup oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index f17be0215d..1ffba40f77 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -21,235 +21,306 @@ --> - rfsim-5gnr-f1 - CU-DU F1 split - wrench - - 111111 - 800813 - 000021 - 000022 - 000023 - 020021 - 030020 - 030021 - 030022 - 040001 - 020022 - 040002 - 030021 - 030022 - 040021 - 000030 - 040022 - 040023 - 020022 - 040024 - 000024 - 000030 - 040025 - 000031 - 030021 - 040027 - 040025 - 000031 - 020022 - 040026 - 040025 - 000031 - 020022 - 040027 - 100021 - 222222 - - + rfsim-5gnr-f1 + CU-DU F1 split + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue-asan - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_f1_rfsimulator - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + - - Deploy_Object - Deploy OAI 5G CU + DU-PCI0 + UE RF sim SA - localhost - ci-scripts/yaml_files/5g_f1_rfsimulator - oai-cu oai-du-pci0 oai-nr-ue - + + Create_Workspace + Create new Workspace + localhost + - - IdleSleep - Sleep - 15 - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_f1_rfsimulator + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - IdleSleep - Sleep - 2 - + + Deploy_Object + Deploy OAI 5G CU + DU-PCI0 + UE RF sim SA + localhost + ci-scripts/yaml_files/5g_f1_rfsimulator + oai-cu oai-du-pci0 oai-nr-ue + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - Deploy_Object - Deploy OAI 5G (target) DU-PCI1 RF sim SA - localhost - ci-scripts/yaml_files/5g_f1_rfsimulator - oai-du-pci1 - + + Ping + Ping ext-dn from all NR-UEs + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.25 + 5 + - - Ping - Ping ext-dn from all NR-UEs - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i0.25 - 5 - + + Custom_Command + Simulate a DL radio channel with noise (3 dB) + localhost + echo channelmod modify 0 noise_power_dB 3 | ncat --send-only 192.168.71.181 8091 + - - Custom_Command - Simulate a DL radio channel with noise (3 dB) - localhost - echo channelmod modify 0 noise_power_dB 3 | ncat --send-only 192.168.71.181 8091 - + + Iperf + Iperf (DL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Iperf - Iperf (DL/3Mbps/UDP)(20 sec) - -u -b 3M -t 20 -R - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Iperf + Iperf (UL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Iperf - Iperf (UL/3Mbps/UDP)(20 sec) - -u -b 3M -t 20 - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Custom_Command + Trigger Reestablishment + localhost + echo ci force_reestab | ncat 192.168.71.171 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' + - - Custom_Command - Trigger Reestablishment - localhost - echo ci force_reestab | ncat 192.168.71.171 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 -w25 + 80 + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i0.5 -w25 - 80 - + + Custom_Command + Verify Reestablishment + localhost + echo ci get_reestab_count | ncat 192.168.71.150 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' + - - Custom_Command - Verify Reestablishment - localhost - echo ci get_reestab_count | ncat 192.168.71.150 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' - + + Iperf + Iperf (DL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Custom_Command - Simulate a disruption of DL radio channel (ploss 55) - localhost - echo channelmod modify 0 ploss 55 | ncat 192.168.71.181 8091 - + + Iperf + Iperf (UL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Custom_Command - Get UE sync state (UE ID 0) - localhost - echo ciUE sync_state 0 | ncat 192.168.71.181 8091 | grep -E UE_NOT_SYNC - + + Custom_Command + Simulate a disruption of DL radio channel (ploss 55) + localhost + echo channelmod modify 0 ploss 55 | ncat 192.168.71.181 8091 + - - Custom_Command - Restoration of the original DL channel conditions (ploss 20) - localhost - echo channelmod modify 0 ploss 20 | ncat 192.168.71.181 8091 - + + IdleSleep + Sleep + 15 + - - Custom_Command - Get UE sync state (UE ID 0) - localhost - echo ciUE sync_state 0 | ncat 192.168.71.181 8091 | grep -E UE_CONNECTED - + + Custom_Command + Get UE sync state (UE ID 0) + localhost + echo ciUE sync_state 0 | ncat 192.168.71.181 8091 | grep -E UE_NOT_SYNC + - - Custom_Command - Trigger Handover - localhost - echo ci trigger_f1_ho | ncat 192.168.71.150 9090 - + + Custom_Command + Restoration of the original DL channel conditions (ploss 20) + localhost + echo channelmod modify 0 ploss 20 | ncat 192.168.71.181 8091 + - - Custom_Command - UE (1) connected to DU-PCI 0? - localhost - echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3584" - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 -w25 + 80 + - - Custom_Command - UE (1) connected to DU-PCI 1? - localhost - echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3585" - + + Custom_Command + Get UE sync state (UE ID 0) + localhost + echo ciUE sync_state 0 | ncat 192.168.71.181 8091 | grep -E UE_CONNECTED + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_f1_rfsimulator - 30,100,100,100 - 30,100,100,100 - + + Deploy_Object + Deploy OAI 5G (target) DU-PCI1 RF sim SA + localhost + ci-scripts/yaml_files/5g_f1_rfsimulator + oai-du-pci1 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue-asan - + + IdleSleep + Sleep + 15 + + + + Custom_Command + Trigger Handover + localhost + echo ci trigger_f1_ho | ncat 192.168.71.150 9090 + + + + IdleSleep + Sleep + 2 + + + + Iperf + Iperf (DL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + + + + Custom_Command + UE (1) connected to DU-PCI 1? + localhost + echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3585" + + + + Custom_Command + Trigger Handover + localhost + echo ci trigger_f1_ho | ncat 192.168.71.150 9090 + + + + IdleSleep + Sleep + 2 + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 -w25 + 80 + + + + Custom_Command + UE (1) connected to DU-PCI 0? + localhost + echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3584" + + + + Custom_Command + Trigger Handover + localhost + echo ci trigger_f1_ho | ncat 192.168.71.150 9090 + + + + IdleSleep + Sleep + 2 + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 -w25 + 80 + + + + Custom_Command + UE (1) connected to DU-PCI 1? + localhost + echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3585" + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_f1_rfsimulator + 30,100,100,100 + 30,100,100,100 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml index 44ccb3a3d2..b4383feeaf 100644 --- a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml @@ -21,120 +21,108 @@ --> - rfsim-5gnr-fdd - Monolithic FDD gNB with SDAP - wrench - - 111111 - 800813 - 000011 - 000012 - 000013 - 020011 - 020012 - 030011 - 030012 - 100011 - 222222 - - + rfsim-5gnr-fdd + Monolithic FDD gNB with SDAP + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb oai-nr-ue - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_fdd_rfsimulator - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb oai-nr-ue + - - Deploy_Object - Deploy OAI 5G gNB+UE RF sim SA - localhost - ci-scripts/yaml_files/5g_fdd_rfsimulator - oai-gnb oai-nr-ue - + + Create_Workspace + Create new Workspace + localhost + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_fdd_rfsimulator + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Deploy_Object + Deploy OAI 5G gNB+UE RF sim SA + localhost + ci-scripts/yaml_files/5g_fdd_rfsimulator + oai-gnb oai-nr-ue + - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_ue - localhost - -c 20 -i 0.25 - 5 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - Iperf - Iperf (DL/3Mbps/UDP)(30 sec) - -u -b 3M -t 30 -R - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Iperf - Iperf (UL/3Mbps/UDP)(30 sec) - -u -b 3M -t 30 - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_fdd_rfsimulator - 1,0,0,0 - 1,0,0,0 - + + Iperf + Iperf (DL/3Mbps/UDP)(30 sec) + -u -b 3M -t 30 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb oai-nr-ue - + + Iperf + Iperf (UL/3Mbps/UDP)(30 sec) + -u -b 3M -t 30 + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_fdd_rfsimulator + 1,0,0,0 + 1,0,0,0 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_flexric_rfsim.xml b/ci-scripts/xml_files/container_5g_flexric_rfsim.xml index 135eab6b68..78fb296697 100644 --- a/ci-scripts/xml_files/container_5g_flexric_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_flexric_rfsim.xml @@ -21,236 +21,206 @@ --> - rfsim-5gnr-flexric - Monolithic SA TDD gNB and FlexRic Integration - wrench - 1 - - 111110 - 111111 - 111112 - 000001 - 000002 - 000003 - 010000 - 000004 - 333333 - 010001 - 010002 - 010003 - 020005 - 002006 - 444444 - 100002 - 100003 - 100004 - 100005 - 100006 - 100007 - 100008 - 100009 - 100001 - 222221 - 222222 - - + rfsim-5gnr-flexric + Monolithic SA TDD gNB and FlexRic Integration + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb oai-nr-ue - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb oai-nr-ue + - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-flexric - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-flexric + - - Clean_Test_Server_Images - Clean Test Images on Test Server - localhost - oai-gnb oai-nr-ue - true - + + Custom_Command + Updating CN5G images + localhost + docker compose -f ../doc/tutorial_resources/oai-cn5g/docker-compose.yaml pull + - - Clean_Test_Server_Images - Clean Test Images on Test Server - localhost - oai-flexric - true - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + doc/tutorial_resources/oai-cn5g + mysql oai-nrf oai-udr oai-udm oai-ausf oai-amf oai-smf oai-upf oai-ext-dn + - - Custom_Command - Updating CN5G images - localhost - docker compose -f ../doc/tutorial_resources/oai-cn5g/docker-compose.yaml pull - + + Deploy_Object + Deploy OAI nearRT-RIC + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + nearRT-RIC + - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - doc/tutorial_resources/oai-cn5g - mysql oai-nrf oai-udr oai-udm oai-ausf oai-amf oai-smf oai-upf oai-ext-dn - + + Deploy_Object + Deploy OAI 5G gNB in RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + oai-gnb + - - Deploy_Object - Deploy OAI nearRT-RIC - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - nearRT-RIC - + + Deploy_Object + Deploy RC monitoring + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + xapp-rc-moni + - - Deploy_Object - Deploy OAI 5G gNB in RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - oai-gnb - + + Deploy_Object + Deploy 2 OAI 5G NR-UEs in RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + oai-nr-ue oai-nr-ue2 + - - Deploy_Object - Deploy 2 OAI 5G NR-UEs in RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - oai-nr-ue oai-nr-ue2 - + + Attach_UE + Attach OAI UE 1 and 2 + rfsim5g_ue rfsim5g_ue2 + carabe + - - Ping - Ping ext-dn from both UEs - rfsim5g_ue rfsim5g_ue2 - carabe - oai_ext_dn - carabe - -c 20 - 5 - + + Deploy_Object + Deploy KPM monitoring + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + xapp-kpm-moni + - - Attach_UE - Attach OAI UE 1 and 2 - rfsim5g_ue rfsim5g_ue2 - carabe - + + Deploy_Object + Deploy KPM monitoring and RC control + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + xapp-kpm-rc + - - Detach_UE - Detach OAI UE 1 and 2 - rfsim5g_ue rfsim5g_ue2 - carabe - + + Deploy_Object + Deploy custom SMs monitoring + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + xapp-gtp-mac-rlc-pdcp-moni + - - Undeploy_Object - Undeploy Core Network - localhost - doc/tutorial_resources/oai-cn5g - true - + + Ping + Ping ext-dn from both UEs + rfsim5g_ue rfsim5g_ue2 + carabe + oai_ext_dn + carabe + -c 20 + 5 + - - Stop_Object - Stop RC monitoring xApp - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - xapp-rc-moni - + + Detach_UE + Detach OAI UE 1 and 2 + rfsim5g_ue rfsim5g_ue2 + carabe + - - Stop_Object - Stop KPM monitoring xApp - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - xapp-kpm-moni - + + Stop_Object + Stop RC monitoring xApp + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + xapp-rc-moni + - - Stop_Object - Stop KPM monitoring and RC control xApp - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - xapp-kpm-rc - + + Stop_Object + Stop KPM monitoring xApp + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + xapp-kpm-moni + - - Stop_Object - Stop custom SMs monitoring xApp - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - xapp-gtp-mac-rlc-pdcp-moni - + + Stop_Object + Stop KPM monitoring and RC control xApp + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + xapp-kpm-rc + - - Stop_Object - Stop OAI UEs - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - oai-nr-ue oai-nr-ue2 - + + Stop_Object + Stop custom SMs monitoring xApp + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + xapp-gtp-mac-rlc-pdcp-moni + - - Stop_Object - Stop OAI gNB - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - oai-gnb - + + Stop_Object + Stop OAI UEs + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + oai-nr-ue oai-nr-ue2 + - - Stop_Object - Stop nearRT-RIC - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - nearRT-RIC - + + Stop_Object + Stop OAI gNB + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + oai-gnb + - - Undeploy_Object - Undeploy RAN and FlexRIC - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - true - + + Stop_Object + Stop nearRT-RIC + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + nearRT-RIC + - - Deploy_Object - Deploy RC monitoring - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - xapp-rc-moni - + + Undeploy_Object + Undeploy RAN and FlexRIC + localhost + ci-scripts/yaml_files/5g_rfsimulator_flexric + true + - - Deploy_Object - Deploy KPM monitoring - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - xapp-kpm-moni - + + Undeploy_Object + Undeploy Core Network + localhost + doc/tutorial_resources/oai-cn5g + true + - - Deploy_Object - Deploy KPM monitoring and RC control - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - xapp-kpm-rc - + + Clean_Test_Server_Images + Clean Test Images on Test Server + localhost + oai-gnb oai-nr-ue + true + - - Deploy_Object - Deploy custom SMs monitoring - localhost - ci-scripts/yaml_files/5g_rfsimulator_flexric - xapp-gtp-mac-rlc-pdcp-moni - + + Clean_Test_Server_Images + Clean Test Images on Test Server + localhost + oai-flexric + true + diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml index 43d2072040..58199ab5d9 100644 --- a/ci-scripts/xml_files/container_5g_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -21,240 +21,238 @@ --> - rfsim-5gnr-tdd - Monolithic SA TDD gNB - wrench - - 111111 - 800813 - 000001 - 000002 - 000003 - 000004 - 000005 - 000006 - 000007 - 000008 - 020001 - 020002 - 020003 - 020004 - 020105 - 444445 - 030001 - 030002 - 444444 - 333333 - 020005 - 444444 - 333333 - 020005 - 100001 - 222222 - - + rfsim-5gnr-tdd + Monolithic SA TDD gNB + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_rfsimulator - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue + - - Deploy_Object - Deploy OAI 5G gNB RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator - oai-gnb - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 5G NR-UE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator - oai-nr-ue - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_rfsimulator + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - Deploy_Object - Deploy Second OAI 5G NR-UE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator - oai-nr-ue2 - + + Deploy_Object + Deploy OAI 5G gNB RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator + oai-gnb + - - Deploy_Object - Deploy OAI 5G NR-UEs (#3, #4, #5) RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator - oai-nr-ue3 oai-nr-ue4 oai-nr-ue5 - + + Deploy_Object + Deploy OAI 5G NR-UE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator + oai-nr-ue + - - Deploy_Object - Deploy OAI 5G NR-UEs (#6, #7, #8) RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator - oai-nr-ue6 oai-nr-ue7 oai-nr-ue8 - + + Deploy_Object + Deploy Second OAI 5G NR-UE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator + oai-nr-ue2 + - - Deploy_Object - Deploy OAI 5G NR-UEs (#9, #10) RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator - oai-nr-ue9 oai-nr-ue10 - + + Deploy_Object + Deploy OAI 5G NR-UEs (#3, #4, #5) RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator + oai-nr-ue3 oai-nr-ue4 oai-nr-ue5 + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10 - localhost - + + Deploy_Object + Deploy OAI 5G NR-UEs (#6, #7, #8) RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator + oai-nr-ue6 oai-nr-ue7 oai-nr-ue8 + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Deploy_Object + Deploy OAI 5G NR-UEs (#9, #10) RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator + oai-nr-ue9 oai-nr-ue10 + - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_ue - localhost - -c 20 -i 0.25 - 5 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10 + localhost + - - Ping - Ping ext-dn from Second NR-UE - rfsim5g_ue2 - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Ping - Ping Second NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_ue2 - localhost - -c 20 -i 0.25 - 5 - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + - - Ping - Ping ext-dn from both UEs - rfsim5g_ue rfsim5g_ue2 - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Ping + Ping ext-dn from Second NR-UE + rfsim5g_ue2 + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Ping - Ping ext-dn from all UEs - rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10 - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 -s 1016 - 5 - + + Ping + Ping Second NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue2 + localhost + -c 20 -i 0.25 + 5 + - - Iperf - Iperf (DL/3Mbps/UDP)(20 sec) - -u -b 3M -t 20 -R - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Ping + Ping ext-dn from all UEs + rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10 + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 -s 1016 + 5 + - - Iperf - Iperf (UL/1Mbps/UDP)(20 sec) - -u -b 1M -t 20 - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Detach_UE + Detach OAI UE 3 to 10 + rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10 + localhost + - - Attach_UE - Attach OAI UE 1 and 2 - rfsim5g_ue rfsim5g_ue2 - localhost - + + Iperf + Iperf (DL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Detach_UE - Detach OAI UE 1 and 2 - rfsim5g_ue rfsim5g_ue2 - localhost - + + Iperf + Iperf (UL/1Mbps/UDP)(20 sec) + -u -b 1M -t 20 + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Detach_UE - Detach OAI UE 3 to 10 - rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10 - localhost - + + Detach_UE + Detach OAI UE 1 and 2 + rfsim5g_ue rfsim5g_ue2 + localhost + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator - 1,0,0,0 - 1,0,0,0 - + + Attach_UE + Attach OAI UE 1 and 2 + rfsim5g_ue rfsim5g_ue2 + localhost + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue - + + Ping + Ping ext-dn from both UEs + rfsim5g_ue rfsim5g_ue2 + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + + + + Detach_UE + Detach OAI UE 1 and 2 + rfsim5g_ue rfsim5g_ue2 + localhost + + + + Attach_UE + Attach OAI UE 1 and 2 + rfsim5g_ue rfsim5g_ue2 + localhost + + + + Ping + Ping ext-dn from both UEs + rfsim5g_ue rfsim5g_ue2 + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator + 1,0,0,0 + 1,0,0,0 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml index b8e01c7edc..1e7128a6e8 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml @@ -21,156 +21,250 @@ --> - rfsim-24prb-5gnr-tdd - Monolithic SA TDD gNB 24PRB - wrench - - 111111 - 800813 - 000001 - 000002 - 000003 - 020001 - 020002 - 030001 - 030002 - 040002 - 000004 - 020001 - 040002 - 000004 - 020001 - 040002 - 000004 - 020001 - 040002 - 000004 - 020001 - 040002 - 000004 - 020001 - 040001 - 000004 - 020001 - 100001 - 222222 - - + rfsim-24prb-5gnr-tdd + Monolithic SA TDD gNB 24PRB + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue-asan - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_rfsimulator_24prb - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + - - Deploy_Object - Deploy OAI 5G gNB+UE RFsim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_24prb - oai-gnb oai-nr-ue - + + Create_Workspace + Create new Workspace + localhost + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_rfsimulator_24prb + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - IdleSleep - Sleep - 1 - + + Deploy_Object + Deploy OAI 5G gNB+UE RFsim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_24prb + oai-gnb oai-nr-ue + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i0.5 - 80 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_ue - localhost - -c 20 -i0.2 - 5 - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 + 80 + - - Iperf - Iperf (DL/3Mbps/UDP)(20 sec) - -u -b 3M -t 20 -R - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i0.2 + 5 + - - Iperf - Iperf (UL/1Mbps/UDP)(20 sec) - -u -b 1M -t 20 - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Iperf + Iperf (DL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Custom_Command - Force Msg3 C-RNTI RA - localhost - echo ciUE force_crnti_ra | ncat 192.168.71.150 8091 - + + Iperf + Iperf (UL/1Mbps/UDP)(20 sec) + -u -b 1M -t 20 + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Custom_Command - Force RRC_IDLE (UE ID 0) - localhost - echo ciUE force_RRC_IDLE | ncat 192.168.71.150 8091 - + + Custom_Command + Force RRC_IDLE (UE ID 0) + localhost + echo ciUE force_RRC_IDLE | ncat 192.168.71.150 8091 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_24prb - + + IdleSleep + Sleep + 1 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue-asan - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 + 80 + + + + Custom_Command + Force RRC_IDLE (UE ID 0) + localhost + echo ciUE force_RRC_IDLE | ncat 192.168.71.150 8091 + + + + IdleSleep + Sleep + 1 + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 + 80 + + + + Custom_Command + Force RRC_IDLE (UE ID 0) + localhost + echo ciUE force_RRC_IDLE | ncat 192.168.71.150 8091 + + + + IdleSleep + Sleep + 1 + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 + 80 + + + + Custom_Command + Force RRC_IDLE (UE ID 0) + localhost + echo ciUE force_RRC_IDLE | ncat 192.168.71.150 8091 + + + + IdleSleep + Sleep + 1 + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 + 80 + + + + Custom_Command + Force RRC_IDLE (UE ID 0) + localhost + echo ciUE force_RRC_IDLE | ncat 192.168.71.150 8091 + + + + IdleSleep + Sleep + 1 + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 + 80 + + + + Custom_Command + Force Msg3 C-RNTI RA + localhost + echo ciUE force_crnti_ra | ncat 192.168.71.150 8091 + + + + IdleSleep + Sleep + 1 + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 + 80 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_24prb + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_rfsim_2x2.xml b/ci-scripts/xml_files/container_5g_rfsim_2x2.xml index 236106d966..06cb9b63db 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_2x2.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_2x2.xml @@ -21,120 +21,108 @@ --> - rfsim-5gnr-tdd-2x2 - Monolithic SA TDD 2x2 gNB - wrench - - 111111 - 800813 - 000001 - 000002 - 000003 - 020001 - 020002 - 030001 - 030002 - 100001 - 222222 - - + rfsim-5gnr-tdd-2x2 + Monolithic SA TDD 2x2 gNB + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue-asan - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_rfsimulator_2x2 - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + - - Deploy_Object - Deploy OAI 5G gNB+UE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_2x2 - oai-gnb oai-nr-ue - + + Create_Workspace + Create new Workspace + localhost + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_rfsimulator_2x2 + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Deploy_Object + Deploy OAI 5G gNB+UE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_2x2 + oai-gnb oai-nr-ue + - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_ue - localhost - -c 20 -i 0.25 - 5 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - Iperf - Iperf (DL/10Mbps/UDP)(20 sec) - -u -b 10M -t 20 -R - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Iperf - Iperf (UL/3Mbps/UDP)(20 sec) - -u -b 3M -t 20 - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_2x2 - 1,0,0,0 - 1,0,0,0 - + + Iperf + Iperf (DL/10Mbps/UDP)(20 sec) + -u -b 10M -t 20 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue-asan - + + Iperf + Iperf (UL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_2x2 + 1,0,0,0 + 1,0,0,0 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml b/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml index 4b695063e7..4fbb0f6f7e 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml @@ -21,120 +21,108 @@ --> - rfsim-5gnr-fdd-phytest - Monolithic FDD phytest gNB - wrench - - 111111 - 800813 - 004000 - 000010 - 000011 - 020011 - 020012 - 030011 - 030012 - 100011 - 222222 - - + rfsim-5gnr-fdd-phytest + Monolithic FDD phytest gNB + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue-asan - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + - - Custom_Command - Clean-Up any residual volume - localhost - docker volume rm 5g_rfsimulator_fdd_phytest_rrc.config -f - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G gNB RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest - oai-gnb - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 5G NR-UE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest - oai-nr-ue - + + Custom_Command + Clean-Up any residual volume + localhost + docker volume rm 5g_rfsimulator_fdd_phytest_rrc.config -f + - - Ping - Ping gNB from NR-UE - rfsim5g_ue - localhost - rfsim5g_gnb_nos1 - localhost - -c20 -i0.2 - 0 - + + Deploy_Object + Deploy OAI 5G gNB RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest + oai-gnb + - - Ping - Ping NR-UE from gNB - rfsim5g_gnb_nos1 - localhost - rfsim5g_ue - localhost - -c20 -i0.2 - 0 - + + Deploy_Object + Deploy OAI 5G NR-UE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest + oai-nr-ue + - - Iperf - Iperf (DL/30kbps/UDP)(20 sec) - -u -b 0.03M -t 20 -R -c 10.0.1.1 - rfsim5g_ue - localhost - rfsim5g_gnb_nos1 - localhost - 5 - 90 - + + Ping + Ping gNB from NR-UE + rfsim5g_ue + localhost + rfsim5g_gnb_nos1 + localhost + -c20 -i0.2 + 0 + - - Iperf - Iperf (UL/30kbps/UDP)(20 sec) - -u -b 0.03M -t 20 -c 10.0.1.1 - rfsim5g_ue - localhost - rfsim5g_gnb_nos1 - localhost - 5 - 90 - + + Ping + Ping NR-UE from gNB + rfsim5g_gnb_nos1 + localhost + rfsim5g_ue + localhost + -c20 -i0.2 + 0 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest - 10,100,100,100 - 10,100,100,100 - + + Iperf + Iperf (DL/30kbps/UDP)(20 sec) + -u -b 0.03M -t 20 -R -c 10.0.1.1 + rfsim5g_ue + localhost + rfsim5g_gnb_nos1 + localhost + 5 + 90 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue-asan - + + Iperf + Iperf (UL/30kbps/UDP)(20 sec) + -u -b 0.03M -t 20 -c 10.0.1.1 + rfsim5g_ue + localhost + rfsim5g_gnb_nos1 + localhost + 5 + 90 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest + 10,100,100,100 + 10,100,100,100 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_rfsim_fr2_32prb.xml b/ci-scripts/xml_files/container_5g_rfsim_fr2_32prb.xml index 224a64c757..5eab626ece 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_fr2_32prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_fr2_32prb.xml @@ -21,96 +21,84 @@ --> - rfsim-fr2-32prb-5gnr-tdd - Monolithic FR2 gNB - wrench - - 111111 - 800813 - 000000 - 000001 - 000013 - 020001 - 020002 - 100001 - 222222 - - + rfsim-fr2-32prb-5gnr-tdd + Monolithic FR2 gNB + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue-asan - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + - - Create_Workspace - Create new Workspace - localhost - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI gNB - localhost - ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Deploy_Object + Deploy OAI gNB + localhost + ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - Deploy_Object - Deploy OAI NR-UE - localhost - ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb - oai-gnb oai-nr-ue - + + Deploy_Object + Deploy OAI NR-UE + localhost + ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb + oai-gnb oai-nr-ue + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i0.2 - 0 - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.2 + 0 + - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_ue - localhost - -c 20 -i0.2 - 0 - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i0.2 + 0 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb - 10,0,0,0 - 10,0,0,0 - + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb + 10,0,0,0 + 10,0,0,0 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue-asan - + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_rfsim_multiue.xml b/ci-scripts/xml_files/container_5g_rfsim_multiue.xml index 8022741c6c..83bd857c4a 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_multiue.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_multiue.xml @@ -21,185 +21,156 @@ --> - rfsim-5gnr-tdd-multiue - Monolithic SA TDD gNB multiue - wrench - - 111111 - 800813 - 000001 - 000002 - 000003 - 000008 - 020001 - 020002 - 020003 - 020004 - 020105 - 444445 - 030001 - 030002 - 444444 - 100001 - 222222 - - + rfsim-5gnr-tdd-multiue + Monolithic SA TDD gNB multiue + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_rfsimulator_multiue - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue + - - Deploy_Object - Deploy OAI 5G gNB RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_multiue - oai-gnb - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 5G NR-UE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_multiue - oai-nr-ue - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_rfsimulator_multiue + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10 - localhost - + + Deploy_Object + Deploy OAI 5G gNB RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_multiue + oai-gnb + - - Ping - Ping ext-dn from NR-UE - rfsim5g_multiue1 - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Deploy_Object + Deploy OAI 5G NR-UE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_multiue + oai-nr-ue + - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_multiue1 - localhost - -c 20 -i 0.25 - 5 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10 + localhost + - - Ping - Ping ext-dn from Second NR-UE - rfsim5g_multiue2 - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Ping + Ping ext-dn from NR-UE + rfsim5g_multiue1 + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Ping - Ping Second NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_multiue2 - localhost - -c 20 -i 0.25 - 5 - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_multiue1 + localhost + -c 20 -i 0.25 + 5 + - - Ping - Ping ext-dn from both UEs - rfsim5g_multiue1 rfsim5g_multiue2 - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Ping + Ping ext-dn from Second NR-UE + rfsim5g_multiue2 + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Ping - Ping ext-dn from all UEs - rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10 - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 -s 1016 - 5 - + + Ping + Ping Second NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_multiue2 + localhost + -c 20 -i 0.25 + 5 + - - Iperf - Iperf (DL/3Mbps/UDP)(20 sec) - -u -b 3M -t 20 -R - rfsim5g_multiue1 - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Ping + Ping ext-dn from all UEs + rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10 + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 -s 1016 + 5 + - - Iperf - Iperf (UL/1Mbps/UDP)(20 sec) - -u -b 1M -t 20 - rfsim5g_multiue1 - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Iperf + Iperf (DL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 -R + rfsim5g_multiue1 + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Detach_UE - Detach OAI UEs - rfsim5g_multiue1 - localhost - + + Iperf + Iperf (UL/1Mbps/UDP)(20 sec) + -u -b 1M -t 20 + rfsim5g_multiue1 + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - ci-scripts/yaml_files/5g_rfsimulator_multiue - 1,0,0,0 - 1,0,0,0 - localhost - + + Detach_UE + Detach OAI UEs + rfsim5g_multiue1 + localhost + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue - + + Undeploy_Object + true + Undeploy all OAI 5G stack + ci-scripts/yaml_files/5g_rfsimulator_multiue + 1,0,0,0 + 1,0,0,0 + localhost + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml b/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml index 37cab0ddb5..6a4d43f93a 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml @@ -21,179 +21,222 @@ --> - rfsim-5gnr-f1-n2-ho - F1 SA TDD N2 Handover - wrench - - 111111 - 800813 - 000001 - 000002 - 000003 - 020001 - 000004 - 040001 - 050001 - 020001 - 020002 - 050002 - 030001 - 030002 - 050003 - 020001 - 020002 - 050004 - 050001 - 020001 - 020002 - 050002 - 100001 - 222222 - - + rfsim-5gnr-f1-n2-ho + F1 SA TDD N2 Handover + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-cuup-asan oai-nr-ue-asan - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-cuup-asan oai-nr-ue-asan + - - Create_Workspace - Create new Workspace - localhost - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_rfsimulator_n2_ho - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_rfsimulator_n2_ho + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - Deploy_Object - Deploy OAI 5G CU-CP/CU-UP/DU 0 + UE RFsim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_n2_ho - oai-cucp-0 oai-cuup-0 oai-du-0 oai-nr-ue - + + Deploy_Object + Deploy OAI 5G CU-CP/CU-UP/DU 0 + UE RFsim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_n2_ho + oai-cucp-0 oai-cuup-0 oai-du-0 oai-nr-ue + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - Deploy_Object - Deploy OAI 5G CU-CP/CU-UP/DU 1 RFsim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_n2_ho - oai-cucp-1 oai-cuup-1 oai-du-1 - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 50 -i 0.25 + 5 + - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_ue - localhost - -c 50 -i 0.25 - 5 - + + Deploy_Object + Deploy OAI 5G CU-CP/CU-UP/DU 1 RFsim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_n2_ho + oai-cucp-1 oai-cuup-1 oai-du-1 + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 50 -i 0.25 - 10 - + + IdleSleep + Sleep + 5 + - - Iperf - Iperf (DL/10Mbps/UDP)(20 sec) - -u -b 3M -t 20 -R - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Custom_Command + Trigger N2 Handover + localhost + echo ci trigger_n2_ho 1,1 | ncat 192.168.71.150 9090 + yes + - - Iperf - Iperf (UL/4Mbps/UDP)(20 sec) - -u -b 1M -t 20 - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 50 -i 0.25 + 5 + - - IdleSleep - Sleep - 5 - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 50 -i 0.25 + 10 + - - Custom_Command - Trigger N2 Handover - localhost - echo ci trigger_n2_ho 1,1 | ncat 192.168.71.150 9090 - yes - + + Custom_Command + UE (1) connected to DU-PCI 1? + localhost + echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.180 9090 | grep "1234" + - - Custom_Command - UE (1) connected to DU-PCI 1? - localhost - echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.180 9090 | grep "1234" - + + Iperf + Iperf (DL/10Mbps/UDP)(20 sec) + -u -b 3M -t 20 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Custom_Command - Trigger N2 Handover - localhost - echo ci trigger_n2_ho 0,1 | ncat 192.168.71.180 9090 - yes - + + Iperf + Iperf (UL/4Mbps/UDP)(20 sec) + -u -b 1M -t 20 + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Custom_Command - UE (1) connected to DU-PCI 0? - localhost - echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3584" - + + Custom_Command + Trigger N2 Handover + localhost + echo ci trigger_n2_ho 0,1 | ncat 192.168.71.180 9090 + yes + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_n2_ho - 10,100,100,100 - 10,100,100,100 - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 50 -i 0.25 + 5 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-cuup-asan oai-nr-ue-asan - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 50 -i 0.25 + 10 + + + + Custom_Command + UE (1) connected to DU-PCI 0? + localhost + echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3584" + + + + Custom_Command + Trigger N2 Handover + localhost + echo ci trigger_n2_ho 1,1 | ncat 192.168.71.150 9090 + yes + + + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 50 -i 0.25 + 5 + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 50 -i 0.25 + 10 + + + + Custom_Command + UE (1) connected to DU-PCI 1? + localhost + echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.180 9090 | grep "1234" + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_n2_ho + 10,100,100,100 + 10,100,100,100 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-cuup-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml b/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml index 66f725ca53..7e291b86fb 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml @@ -21,125 +21,131 @@ --> - rfsim-5gnr-ntn-geo - Monolithic SA NTN GEO gNB - wrench - - 111111 - 800813 - 000001 - 000002 - 000003 - 020001 - 020002 - 040001 - 020022 - 040002 - 020001 - 020002 - 100001 - 222222 - - + rfsim-5gnr-ntn-geo + Monolithic SA NTN GEO gNB + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue-asan - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_rfsimulator_ntn_geo - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 5G gNB+nrUE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_ntn_geo - oai-gnb oai-nr-ue - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_rfsimulator_ntn_geo + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Deploy_Object + Deploy OAI 5G gNB+nrUE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_ntn_geo + oai-gnb oai-nr-ue + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_ue - localhost - -c 20 -i 0.25 - 5 - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Custom_Command - Trigger Reestablishment - localhost - echo ci force_reestab | ncat 192.168.71.140 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' - yes - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i0.5 -w25 - 80 - + + Custom_Command + Trigger Reestablishment + localhost + echo ci force_reestab | ncat 192.168.71.140 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' + yes + - - Custom_Command - Verify Reestablishment - localhost - echo ci get_reestab_count | ncat 192.168.71.140 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' - yes - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 -w25 + 80 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_ntn_geo - + + Custom_Command + Verify Reestablishment + localhost + echo ci get_reestab_count | ncat 192.168.71.140 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' + yes + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue-asan - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + + + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_ntn_geo + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml b/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml index cde84b00e7..cac6f5f4ee 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml @@ -21,93 +21,131 @@ --> - rfsim-5gnr-ntn-Leo - Monolithic SA NTN LEO gNB - wrench - - 111111 - 800813 - 000001 - 000002 - 000003 - 020001 - 020002 - 100001 - 222222 - - + rfsim-5gnr-ntn-Leo + Monolithic SA NTN LEO gNB + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue-asan - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_rfsimulator_ntn_leo - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 5G gNB+nrUE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_ntn_leo - oai-gnb oai-nr-ue - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_rfsimulator_ntn_leo + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Deploy_Object + Deploy OAI 5G gNB+nrUE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_ntn_leo + oai-gnb oai-nr-ue + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_ue - localhost - -c 20 -i 0.25 - 5 - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_ntn_leo - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue-asan - + + Custom_Command + Trigger Reestablishment + localhost + echo ci force_reestab | ncat 192.168.71.140 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' + yes + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i0.5 -w25 + 80 + + + + Custom_Command + Verify Reestablishment + localhost + echo ci get_reestab_count | ncat 192.168.71.140 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' + yes + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + + + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_ntn_leo + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_rfsim_prs.xml b/ci-scripts/xml_files/container_5g_rfsim_prs.xml index bbc287ff76..2485e7d503 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_prs.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_prs.xml @@ -21,80 +21,69 @@ --> - rfsim-5gnr-prs - Monolithic gNB with PRS - wrench - - 111111 - 800813 - 000012 - 000013 - 040001 - 040023 - 100011 - 222222 - - + rfsim-5gnr-prs + Monolithic gNB with PRS + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue-asan - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + - - Create_Workspace - Create new Workspace - localhost - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 5G gNB+UE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_prs - oai-gnb oai-nr-ue - + + Deploy_Object + Deploy OAI 5G gNB+UE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_prs + oai-gnb oai-nr-ue + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - IdleSleep - Sleep - 2 - + + IdleSleep + Sleep + 2 + - - Custom_Script - true - Set and verify distance at 50, 100, 150 m - localhost - - 50 100 150 - + + Custom_Script + true + Set and verify distance at 50, 100, 150 m + localhost + + 50 100 150 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_prs - 30,100,100,100 - 30,100,100,100 - + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_prs + 30,100,100,100 + 30,100,100,100 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue-asan - + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml b/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml index 6ddd6d13b7..f434bb600c 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml @@ -21,79 +21,68 @@ --> - rfsim-5gnr-sidelink - Sidelink test - wrench - - 111111 - 800813 - 000002 - 000003 - 000004 - 000005 - 100001 - 222222 - - + rfsim-5gnr-sidelink + Sidelink test + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-nr-ue-asan - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-nr-ue-asan + - - Create_Workspace - Create new Workspace - localhost - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI 5G UE 1 - localhost - ci-scripts/yaml_files/5g_rfsimulator_sidelink - oai-nr-ue-1 - - - - Deploy_Object - Deploy OAI 5G UE 2 - localhost - ci-scripts/yaml_files/5g_rfsimulator_sidelink - oai-nr-ue-2 - + + Deploy_Object + Deploy OAI 5G UE 1 + localhost + ci-scripts/yaml_files/5g_rfsimulator_sidelink + oai-nr-ue-1 + - - IdleSleep - Sleep - 20 - + + Deploy_Object + Deploy OAI 5G UE 2 + localhost + ci-scripts/yaml_files/5g_rfsimulator_sidelink + oai-nr-ue-2 + - - Custom_Command - Check that UE synched - localhost - docker logs rfsim5g-oai-nr-ue-2 | grep -m 1 "PSBCH RX:OK" - + + IdleSleep + Sleep + 20 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_sidelink - 1,0,0,0 - 1,0,0,0 - + + Custom_Command + Check that UE synched + localhost + docker logs rfsim5g-oai-nr-ue-2 | grep -m 1 "PSBCH RX:OK" + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-nr-ue-asan - + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_sidelink + 1,0,0,0 + 1,0,0,0 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_rfsim_simple.xml b/ci-scripts/xml_files/container_5g_rfsim_simple.xml index 3dd5a560e0..be4912d2b2 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_simple.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_simple.xml @@ -21,77 +21,67 @@ --> - rfsim-5gnr-tdd - Monolithic SA TDD gNB - wrench - - 000001 - 000002 - 000003 - 000008 - 020001 - 444444 - 100001 - - + rfsim-5gnr-tdd + Monolithic SA TDD gNB + wrench - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_rfsimulator - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_rfsimulator + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - Deploy_Object - Deploy OAI 5G gNB RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator - oai-gnb - + + Deploy_Object + Deploy OAI 5G gNB RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator + oai-gnb + - - Deploy_Object - Deploy OAI 5G NR-UE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator - oai-nr-ue - + + Deploy_Object + Deploy OAI 5G NR-UE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator + oai-nr-ue + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Detach_UE - Detach OAI UE 1 - rfsim5g_ue - localhost - + + Detach_UE + Detach OAI UE 1 + rfsim5g_ue + localhost + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator - 1,0,0,0 - 1,0,0,0 - + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator + 1,0,0,0 + 1,0,0,0 + diff --git a/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml b/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml index 6a09b8138d..83209d664e 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml @@ -21,102 +21,97 @@ --> - rfsim-tdd-dora-5gnr-tdd - Monolithic do-ra TDD gNB - wrench - - 111111 - 800813 - 004000 - 000000 - 000001 - 000030 - 020001 - 020002 - 100001 - 004000 - 222222 - - + rfsim-tdd-dora-5gnr-tdd + Monolithic do-ra TDD gNB + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue-asan - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + - - Custom_Command - Clean-Up any residual volume - localhost - docker volume rm 5g_rfsimulator_tdd_dora_rrc.config -f - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI gNB - localhost - ci-scripts/yaml_files/5g_rfsimulator_tdd_dora - oai-gnb - + + Create_Workspace + Create new Workspace + localhost + - - Deploy_Object - Deploy OAI NR-UE - localhost - ci-scripts/yaml_files/5g_rfsimulator_tdd_dora - oai-nr-ue - + + Custom_Command + Clean-Up any residual volume + localhost + docker volume rm 5g_rfsimulator_tdd_dora_rrc.config -f + - - IdleSleep - Sleep - 5 - + + Deploy_Object + Deploy OAI gNB + localhost + ci-scripts/yaml_files/5g_rfsimulator_tdd_dora + oai-gnb + - - Ping - Ping gNB from NR-UE - rfsim5g_ue - localhost - rfsim5g_gnb_nos1 - localhost - -c20 -i0.2 - 0 - + + Deploy_Object + Deploy OAI NR-UE + localhost + ci-scripts/yaml_files/5g_rfsimulator_tdd_dora + oai-nr-ue + - - Ping - Ping NR-UE from gNB - rfsim5g_gnb_nos1 - localhost - rfsim5g_ue - localhost - -c20 -i0.2 - 0 - + + IdleSleep + Sleep + 5 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_tdd_dora - 0,0,0,0 - 0,0,0,0 - + + Ping + Ping gNB from NR-UE + rfsim5g_ue + localhost + rfsim5g_gnb_nos1 + localhost + -c20 -i0.2 + 0 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue-asan - + + Ping + Ping NR-UE from gNB + rfsim5g_gnb_nos1 + localhost + rfsim5g_ue + localhost + -c20 -i0.2 + 0 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_tdd_dora + 0,0,0,0 + 0,0,0,0 + + + + Custom_Command + Clean-Up any residual volume + localhost + docker volume rm 5g_rfsimulator_tdd_dora_rrc.config -f + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml b/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml index 3bb99de4ab..060f539cde 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml @@ -21,166 +21,169 @@ --> - rfsim-5gnr-fdd-u0-25prb - VNF-PNF nFAPI FDD u0 25PRB gNB - wrench - - 111111 - 800813 - 000001 - 000002 - 000003 - 020001 - 020002 - 000004 - 020003 - 030001 - 030002 - 050001 - 050002 - 050003 - 020001 - 020002 - 100001 - 222222 - - + rfsim-5gnr-fdd-u0-25prb + VNF-PNF nFAPI FDD u0 25PRB gNB + wrench - - Pull_Local_Registry - Pull Images from Local Registry - localhost - oai-gnb-asan oai-nr-ue-asan - - - Create_Workspace - Create new Workspace - localhost - - - Deploy_Object - Deploy OAI 5G CoreNetwork - localhost - ci-scripts/yaml_files/5g_rfsimulator_u0_25prb - mysql oai-amf oai-smf oai-upf oai-ext-dn - + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + - - Deploy_Object - Deploy OAI 5G VNF+PNF+nrUE RF sim SA - localhost - ci-scripts/yaml_files/5g_rfsimulator_u0_25prb - oai-vnf oai-pnf oai-nr-ue - + + Create_Workspace + Create new Workspace + localhost + - - Attach_UE - Attach OAI UE (Wait for IP) - rfsim5g_ue - localhost - + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_rfsimulator_u0_25prb + mysql oai-amf oai-smf oai-upf oai-ext-dn + - - Ping - Ping ext-dn from NR-UE - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Deploy_Object + Deploy OAI 5G VNF+PNF+nrUE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_u0_25prb + oai-vnf oai-pnf oai-nr-ue + - - Ping - Ping NR-UE from ext-dn - rfsim5g_ext_dn - localhost - rfsim5g_ue - localhost - -c 20 -i 0.25 - 5 - + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + - - Attach_UE - Verify 2nd PDU session is up - rfsim5g_ue_pdu_2 - localhost - + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Ping - Ping ext-dn from NR-UE on PDU session ID 2 - rfsim5g_ue_pdu_2 - localhost - rfsim5g_ext_dn - localhost - -c 20 -i 0.25 - 5 - + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + - - Iperf - Iperf (DL/3Mbps/UDP)(20 sec) - -u -b 3M -t 20 -R - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Attach_UE + Verify 2nd PDU session is up + rfsim5g_ue_pdu_2 + localhost + - - Iperf - Iperf (UL/1Mbps/UDP)(20 sec) - -u -b 1M -t 20 - rfsim5g_ue - localhost - rfsim5g_ext_dn - localhost - 5 - 90 - + + Ping + Ping ext-dn from NR-UE on PDU session ID 2 + rfsim5g_ue_pdu_2 + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + - - Custom_Command - Trigger PDU Session Release via gNB telnet - acamas - echo ci pdu_session_release 2 | ncat 192.168.71.140 9090 - + + Iperf + Iperf (DL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Custom_Command - Add PDU Session via UE telnet - acamas - echo ci add_pdu_session 6,7 | ncat 192.168.71.150 8091 - + + Iperf + Iperf (UL/1Mbps/UDP)(20 sec) + -u -b 1M -t 20 + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + - - Custom_Command - Trigger PDU Session Release via gNB telnet - acamas - echo ci pdu_session_release 6 | ncat 192.168.71.140 9090 - + + Custom_Command + Trigger PDU Session Release via gNB telnet + acamas + echo ci pdu_session_release 2 | ncat 192.168.71.140 9090 + - - Undeploy_Object - true - Undeploy all OAI 5G stack - localhost - ci-scripts/yaml_files/5g_rfsimulator_u0_25prb - 1,0,0,0 - 1,0,0,0 - + + Custom_Command + Add PDU Session via UE telnet + acamas + echo ci add_pdu_session 6,7 | ncat 192.168.71.150 8091 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - localhost - oai-gnb-asan oai-nr-ue-asan - + + Custom_Command + Trigger PDU Session Release via gNB telnet + acamas + echo ci pdu_session_release 6 | ncat 192.168.71.140 9090 + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + + + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_u0_25prb + 1,0,0,0 + 1,0,0,0 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + diff --git a/ci-scripts/xml_files/container_5g_vrtsim_chanmod.xml b/ci-scripts/xml_files/container_5g_vrtsim_chanmod.xml new file mode 100644 index 0000000000..c844228640 --- /dev/null +++ b/ci-scripts/xml_files/container_5g_vrtsim_chanmod.xml @@ -0,0 +1,128 @@ + + + vrtsim-5gnr-chanmod + Monolithic gNB vrtsim + chanmod + wrench + + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb oai-nr-ue + + + + Create_Workspace + Create new Workspace + localhost + + + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_vrtsim_chanmod + mysql oai-amf oai-smf oai-upf oai-ext-dn + + + + Deploy_Object + Deploy OAI 5G gNB+UE RF sim SA + localhost + ci-scripts/yaml_files/5g_vrtsim_chanmod + oai-gnb oai-nr-ue + + + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + + + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + + + + Iperf + Iperf (DL/3Mbps/UDP)(20 sec) + -u -b 3M -t 20 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + + + + Iperf + Iperf (UL/1Mbps/UDP)(20 sec) + -u -b 1M -t 20 + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_vrtsim_chanmod + 1,0,0,0 + 1,0,0,0 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb oai-nr-ue + + + diff --git a/ci-scripts/xml_files/container_5g_vrtsim_chanmod_gh.xml b/ci-scripts/xml_files/container_5g_vrtsim_chanmod_gh.xml new file mode 100644 index 0000000000..3d3a9a5e41 --- /dev/null +++ b/ci-scripts/xml_files/container_5g_vrtsim_chanmod_gh.xml @@ -0,0 +1,129 @@ + + + vrtsim-5gnr-chanmod-gh + Monolithic gNB vrtsim + chanmod + wrench + + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb oai-nr-ue + arm_ + + + + Create_Workspace + Create new Workspace + localhost + + + + Deploy_Object + Deploy OAI 5G CoreNetwork + localhost + ci-scripts/yaml_files/5g_vrtsim_chanmod + mysql oai-amf oai-smf oai-upf oai-ext-dn + + + + Deploy_Object + Deploy OAI 5G gNB+UE RF sim SA + localhost + ci-scripts/yaml_files/5g_vrtsim_chanmod + oai-gnb oai-nr-ue + + + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + + + + Ping + Ping ext-dn from NR-UE + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + -c 20 -i 0.25 + 5 + + + + Ping + Ping NR-UE from ext-dn + rfsim5g_ext_dn + localhost + rfsim5g_ue + localhost + -c 20 -i 0.25 + 5 + + + + Iperf + Iperf (DL/3Mbps/UDP)(30 sec) + -u -b 3M -t 30 -R + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + + + + Iperf + Iperf (UL/1Mbps/UDP)(30 sec) + -u -b 1M -t 30 + rfsim5g_ue + localhost + rfsim5g_ext_dn + localhost + 5 + 90 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_vrtsim_chanmod + 1,0,0,0 + 1,0,0,0 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb oai-nr-ue + + + diff --git a/ci-scripts/xml_files/container_build_run_tests.xml b/ci-scripts/xml_files/container_build_run_tests.xml index 087c5af598..85e0cd53da 100644 --- a/ci-scripts/xml_files/container_build_run_tests.xml +++ b/ci-scripts/xml_files/container_build_run_tests.xml @@ -21,19 +21,15 @@ --> - build-run-test-tab - Build and Run Unit Tests - wrench - - 030201 - - + build-run-test-tab + Build and Run Unit Tests + wrench - - Build_Run_Tests - Build and Run UnitTests - obelix - all - + + Build_Run_Tests + Build and Run UnitTests + obelix + all + diff --git a/ci-scripts/xml_files/container_image_build.xml b/ci-scripts/xml_files/container_image_build.xml index afd58d4d6d..85966f0214 100644 --- a/ci-scripts/xml_files/container_image_build.xml +++ b/ci-scripts/xml_files/container_image_build.xml @@ -21,32 +21,27 @@ --> - build-tab - Build Container Images - wrench - - 800813 - 000001 - 000010 - - + build-tab + Build Container Images + wrench - - Create_Workspace - Create new Workspace for server 0 - obelix - - - Build_Image - Build all Images - obelix - all - + + Create_Workspace + Create new Workspace for server 0 + obelix + - - Push_Local_Registry - Push Images to Local Registry - obelix - + + Build_Image + Build all Images + obelix + all + + + + Push_Local_Registry + Push Images to Local Registry + obelix + diff --git a/ci-scripts/xml_files/container_image_build_arm.xml b/ci-scripts/xml_files/container_image_build_arm.xml index f5daa348aa..1d83101fdd 100644 --- a/ci-scripts/xml_files/container_image_build_arm.xml +++ b/ci-scripts/xml_files/container_image_build_arm.xml @@ -21,33 +21,28 @@ --> - build-tab - Build Container Images for ARM - wrench - - 800813 - 000001 - 000010 - - + build-tab + Build Container Images for ARM + wrench - - Create_Workspace - Create new Workspace for server 0 - gracehopper3-oai - - - Build_Image - Build all Images - gracehopper3-oai - native_armv9 - + + Create_Workspace + Create new Workspace for server 0 + gracehopper3-oai + - - Push_Local_Registry - Push Images to Local Registry - gracehopper3-oai - arm_ - + + Build_Image + Build all Images + gracehopper3-oai + native_armv9 + + + + Push_Local_Registry + Push Images to Local Registry + gracehopper3-oai + arm_ + diff --git a/ci-scripts/xml_files/container_image_build_cross.xml b/ci-scripts/xml_files/container_image_build_cross.xml index ab94d847c8..592d097a73 100644 --- a/ci-scripts/xml_files/container_image_build_cross.xml +++ b/ci-scripts/xml_files/container_image_build_cross.xml @@ -21,24 +21,21 @@ --> - build-tab - Build Container Images - wrench - - 100001 - 000001 - - - - Create_Workspace - Create new Workspace - alambix - - - Build_Image - Cross-Compile for ARM64 - build_cross_arm64 - alambix - + build-tab + Build Container Images + wrench + + + Create_Workspace + Create new Workspace + alambix + + + + Build_Image + Cross-Compile for ARM64 + build_cross_arm64 + alambix + diff --git a/ci-scripts/xml_files/container_image_build_jetson.xml b/ci-scripts/xml_files/container_image_build_jetson.xml index 3cdac5efcb..7b77a77277 100644 --- a/ci-scripts/xml_files/container_image_build_jetson.xml +++ b/ci-scripts/xml_files/container_image_build_jetson.xml @@ -21,33 +21,28 @@ --> - build-tab - Build Container Images for ARM - wrench - - 800813 - 000001 - 000010 - - + build-tab + Build Container Images for ARM + wrench - - Create_Workspace - Create new Workspace for server 0 - jetson3-oai - - - Build_Image - Build all Images - jetson3-oai - native_armv8 - + + Create_Workspace + Create new Workspace for server 0 + jetson3-oai + - - Push_Local_Registry - Push Images to Local Registry - jetson3-oai - armv8_ - + + Build_Image + Build all Images + jetson3-oai + native_armv8 + + + + Push_Local_Registry + Push Images to Local Registry + jetson3-oai + armv8_ + diff --git a/ci-scripts/xml_files/container_l2sim_proxy.xml b/ci-scripts/xml_files/container_l2sim_proxy.xml index c2f19f9471..4f1cea9263 100644 --- a/ci-scripts/xml_files/container_l2sim_proxy.xml +++ b/ci-scripts/xml_files/container_l2sim_proxy.xml @@ -21,19 +21,15 @@ --> - l2sim-4glte-5gnr-proxy-build - Build L2sim proxy image - wrench - - 000001 - - + l2sim-4glte-5gnr-proxy-build + Build L2sim proxy image + wrench - - Build_Proxy - Build L2sim Proxy Image - localhost - b64d9bce986b38ca59e8582864ade3fcdd05c0dc - + + Build_Proxy + Build L2sim Proxy Image + localhost + b64d9bce986b38ca59e8582864ade3fcdd05c0dc + diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml index 10ab1fd3b0..614acee309 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml @@ -23,195 +23,182 @@ Replaces xml_files/enb_usrp210_band7_test_05mhz_tm1.xml --> - test-fdd-05-tm1 - Test-FDD-05MHz-TM1 - tasks - -100000 -111110 -300000 -040101 -800813 -030101 -040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 -030201 -200000 -222222 - - + test-fdd-05-tm1 + Test-FDD-05MHz-TM1 + tasks - - Pull_Local_Registry - Pull Images from Local Registry - hutch - oai-enb - + + Custom_Command + Disable Sleep States + hutch + sudo cpupower idle-set -D 0 + - - Custom_Command - Disable Sleep States - hutch - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - hutch - sudo cpupower idle-set -E - - - Custom_Command - Reset USRP - hutch - sudo -S b2xx_fx3_utils --reset-device - - - Create_Workspace - Create new Workspace for server 0 - hutch - - - Deploy_Object - Deploy eNB (FDD/Band7/5MHz/B200) in a container - hutch - ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1 - + + Pull_Local_Registry + Pull Images from Local Registry + hutch + oai-enb + - - IdleSleep - Sleep - 5 - + + Custom_Command + Reset USRP + hutch + sudo -S b2xx_fx3_utils --reset-device + - - Undeploy_Object - true - Undeploy eNB - hutch - ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1 - + + Initialize_UE + Initialize UE + adb_ue_1 adb_ue_2 + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UEs - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UEs - adb_ue_1 adb_ue_2 - + + Create_Workspace + Create new Workspace for server 0 + hutch + - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Deploy_Object + Deploy eNB (FDD/Band7/5MHz/B200) in a container + hutch + ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1 + - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) - -u -b 15M -t 30 -R - 50 - 50 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Attach_UE + Attach UEs + adb_ue_1 adb_ue_2 + - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) - -u -b 15M -t 30 -R - 50 - adb_ue_1 - ltebox-nano - + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile) - -u -b 15M -t 30 -R - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) + -u -b 15M -t 30 -R + 50 + 50 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -R - adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) + -u -b 15M -t 30 -R + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (5MHz - DL/TCP)(30 sec)(balanced profile) - -t 30 -R - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile) + -u -b 15M -t 30 -R + 50 + unbalanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) - -u -b 9M -t 30 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -R + adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) - -u -b 9M -t 30 - 50 - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(balanced profile) + -t 30 -R + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) + -u -b 9M -t 30 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) + -u -b 9M -t 30 + 50 + 50 + adb_ue_1 + ltebox-nano + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - hutch - oai-enb - + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) + -t 30 + adb_ue_1 + ltebox-nano + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(balanced profile) + -t 30 + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Detach_UE + true + Detach UEs + adb_ue_1 adb_ue_2 + + + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + + + + Undeploy_Object + true + Undeploy eNB + hutch + ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1 + + + + Custom_Command + true + Enable Sleep States + hutch + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + hutch + oai-enb + - diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml index ebc59e746d..243243658b 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml @@ -21,178 +21,166 @@ --> - test-fdd-05-tm1-if4-5 - Test-FDD-05MHz-TM1-IF4.5 - tasks - -100000 -111110 -300000 -040101 -800813 -030131 -030132 -040301 040531 040633 040634 040636 040671 040672 040673 040401 040201 -030231 -200000 -222222 - - + test-fdd-05-tm1-if4-5 + Test-FDD-05MHz-TM1-IF4.5 + tasks - - Pull_Local_Registry - Pull Images from Local Registry - hutch - oai-enb - + + Custom_Command + Disable Sleep States + hutch + sudo cpupower idle-set -D 0 + - - Custom_Command - Disable Sleep States - hutch - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - hutch - sudo cpupower idle-set -E - - - Custom_Command - Reset USRP - hutch - sudo -S b2xx_fx3_utils --reset-device - - - Create_Workspace - Create new Workspace for server 0 - hutch - - - Deploy_Object - Deploy RRU (FDD/Band7/5MHz/B200) in a container - hutch - ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5 - rru_fdd - - - Deploy_Object - Deploy RCC (FDD/Band7/5MHz) in a container - hutch - ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5 - rcc_fdd - + + Pull_Local_Registry + Pull Images from Local Registry + hutch + oai-enb + - - IdleSleep - Sleep - 5 - + + Custom_Command + Reset USRP + hutch + sudo -S b2xx_fx3_utils --reset-device + - - Undeploy_Object - true - Undeploy RCC/RRU - hutch - ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5 - + + Initialize_UE + Initialize UE + adb_ue_1 adb_ue_2 + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UEs - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UEs - adb_ue_1 adb_ue_2 - + + Create_Workspace + Create new Workspace for server 0 + hutch + - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Deploy_Object + Deploy RRU (FDD/Band7/5MHz/B200) in a container + hutch + ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5 + rru_fdd + - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) - -u -b 15M -t 30 -R - 50 - 50 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Deploy_Object + Deploy RCC (FDD/Band7/5MHz) in a container + hutch + ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5 + rcc_fdd + - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) - -u -b 15M -t 30 -R - 50 - adb_ue_1 - ltebox-nano - + + Attach_UE + Attach UEs + adb_ue_1 adb_ue_2 + - - Iperf - iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -R - adb_ue_2 - ltebox-nano - + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) - -u -b 9M -t 30 - 50 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) + -u -b 15M -t 30 -R + 50 + 50 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) - -u -b 9M -t 30 - 50 - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) + -u -b 15M -t 30 -R + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -R + adb_ue_2 + ltebox-nano + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - hutch - oai-enb - + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) + -u -b 9M -t 30 + 50 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) + -u -b 9M -t 30 + 50 + 50 + adb_ue_1 + ltebox-nano + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) + -t 30 + adb_ue_1 + ltebox-nano + + + + Detach_UE + true + Detach UEs + adb_ue_1 adb_ue_2 + + + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + + + + Undeploy_Object + true + Undeploy RCC/RRU + hutch + ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5 + + + + Custom_Command + true + Enable Sleep States + hutch + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + hutch + oai-enb + diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_no_rrc_activity.xml b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_no_rrc_activity.xml index 8936a3928e..bd7400cb13 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_no_rrc_activity.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_no_rrc_activity.xml @@ -23,161 +23,155 @@ Replaces xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xm --> - test-fdd-05-rrc-inactivity - Test-FDD-05MHz-TM1-RRC-Inactivity - tasks - -100000 -111110 -040101 -800813 -030102 -000010 040301 040502 000011 040302 000001 000012 040303 000002 000013 040503 040401 040201 -030202 -200000 -222222 - - + test-fdd-05-rrc-inactivity + Test-FDD-05MHz-TM1-RRC-Inactivity + tasks - - Pull_Local_Registry - Pull Images from Local Registry - hutch - oai-enb - - - Custom_Command - Disable Sleep States - hutch - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - hutch - sudo cpupower idle-set -E - - - Create_Workspace - Create new Workspace for server 0 - hutch - - - Deploy_Object - Deploy eNB (FDD/Band7/5MHz/B200) in a container - hutch - ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1_no_rrc_activity - + + Custom_Command + Disable Sleep States + hutch + sudo cpupower idle-set -D 0 + - - Undeploy_Object - true - Undeploy eNB - hutch - ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1_no_rrc_activity - + + Pull_Local_Registry + Pull Images from Local Registry + hutch + oai-enb + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UE - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UE - adb_ue_1 adb_ue_2 - + + Initialize_UE + Initialize UE + adb_ue_1 adb_ue_2 + - - IdleSleep - Waiting for 55 seconds - 55 - + + Create_Workspace + Create new Workspace for server 0 + hutch + - - IdleSleep - Waiting for 10 seconds - 10 - + + Deploy_Object + Deploy eNB (FDD/Band7/5MHz/B200) in a container + hutch + ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1_no_rrc_activity + - - CheckStatusUE - Check UE(s) status before attachment - 0 - adb_ue_1 adb_ue_2 - + + CheckStatusUE + Check UE(s) status before attachment + 0 + adb_ue_1 adb_ue_2 + - - CheckStatusUE - Check UE(s) status before data disabling - 2 - adb_ue_1 adb_ue_2 - + + Attach_UE + Attach UE + adb_ue_1 adb_ue_2 + - - CheckStatusUE - Check UE(s) status after data disabling - 0 - adb_ue_1 adb_ue_2 - + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + adb_ue_1 adb_ue_2 + ltebox-nano + - - CheckStatusUE - Check UE(s) status after data re-enabling - 2 - adb_ue_1 adb_ue_2 - + + CheckStatusUE + Check UE(s) status before data disabling + 2 + adb_ue_1 adb_ue_2 + - - DataDisable_UE - Disabling Data Service on UE - adb_ue_1 adb_ue_2 - + + DataDisable_UE + Disabling Data Service on UE + adb_ue_1 adb_ue_2 + - - DataEnable_UE - Enabling Data Service on UE - adb_ue_1 adb_ue_2 - + + IdleSleep + Waiting for 55 seconds + 55 + - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 - adb_ue_1 adb_ue_2 - ltebox-nano - + + CheckStatusUE + Check UE(s) status after data disabling + 0 + adb_ue_1 adb_ue_2 + - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 - adb_ue_1 adb_ue_2 - ltebox-nano - + + DataEnable_UE + Enabling Data Service on UE + adb_ue_1 adb_ue_2 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - hutch - oai-enb - + + IdleSleep + Waiting for 10 seconds + 10 + + + + CheckStatusUE + Check UE(s) status after data re-enabling + 2 + adb_ue_1 adb_ue_2 + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Detach_UE + true + Detach UE + adb_ue_1 adb_ue_2 + + + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + + + + Undeploy_Object + true + Undeploy eNB + hutch + ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1_no_rrc_activity + + + + Custom_Command + true + Enable Sleep States + hutch + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + hutch + oai-enb + - diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml index 1456418475..92f4376676 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml @@ -24,189 +24,166 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml 040301 040511 040613 040614 040615 040616 040617 040651 040652 040653 040654 040401 040201 --> - test-fdd-10-tm1 - Test-FDD-10MHz-TM1 - tasks - -100000 -111110 -040101 -800813 -030111 -000001 -040301 040511 040613 040614 040615 040651 040652 040653 040654 040401 040201 -030211 -200000 -222222 - - + test-fdd-10-tm1 + Test-FDD-10MHz-TM1 + tasks - - Pull_Local_Registry - Pull Images from Local Registry - hutch - oai-enb - - - Custom_Command - Disable Sleep States - hutch - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - hutch - sudo cpupower idle-set -E - - - Create_Workspace - Create new Workspace for server 0 - hutch - - - Deploy_Object - Deploy eNB (FDD/Band7/10MHz/B200) in a container - hutch - ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1 - + + Custom_Command + Disable Sleep States + hutch + sudo cpupower idle-set -D 0 + - - IdleSleep - Sleep - 5 - + + Pull_Local_Registry + Pull Images from Local Registry + hutch + oai-enb + - - Undeploy_Object - true - Undeploy eNB - hutch - ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1 - + + Initialize_UE + Initialize UE + adb_ue_1 adb_ue_2 + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UE - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UE - adb_ue_1 adb_ue_2 - + + Create_Workspace + Create new Workspace for server 0 + hutch + - - Ping - ping (10MHz - 20 sec) - -c 20 - 5 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Deploy_Object + Deploy eNB (FDD/Band7/10MHz/B200) in a container + hutch + ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1 + - - Iperf - iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile) - -u -b 30M -t 30 -R - 50 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + IdleSleep + Sleep + 5 + - - Iperf - iperf (10MHz - DL/30Mbps/UDP)(30 sec)(single-ue profile) - -u -b 30M -t 30 -R - 50 - adb_ue_1 - ltebox-nano - + + Attach_UE + Attach UE + adb_ue_1 adb_ue_2 + - - Iperf - iperf (10MHz - DL/30Mbps/UDP)(30 sec)(unbalanced profile) - -u -b 30M -t 30 -R - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Ping + ping (10MHz - 20 sec) + -c 20 + 5 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (10MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -R - adb_ue_1 - ltebox-nano - + + Iperf + iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile) + -u -b 30M -t 30 -R + 50 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (10MHz - DL/TCP)(30 sec)(balanced profile) - -t 30 -R - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (10MHz - DL/30Mbps/UDP)(30 sec)(single-ue profile) + -u -b 30M -t 30 -R + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (10MHz - UL/18Mbps/UDP)(30 sec)(balanced profile) - -u -b 18M -t 30 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (10MHz - DL/30Mbps/UDP)(30 sec)(unbalanced profile) + -u -b 30M -t 30 -R + 50 + unbalanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (10MHz - UL/18Mbps/UDP)(30 sec)(single-ue profile) - -u -b 18M -t 30 - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (10MHz - UL/18Mbps/UDP)(30 sec)(balanced profile) + -u -b 18M -t 30 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (10MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (10MHz - UL/18Mbps/UDP)(30 sec)(single-ue profile) + -u -b 18M -t 30 + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (10MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (10MHz - UL/TCP)(30 sec)(single-ue profile) + -t 30 + adb_ue_1 + ltebox-nano + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - hutch - oai-enb - + + Iperf + iperf (10MHz - UL/TCP)(30 sec)(balanced profile) + -t 30 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Detach_UE + true + Detach UE + adb_ue_1 adb_ue_2 + + + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + + + + Undeploy_Object + true + Undeploy eNB + hutch + ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1 + + + + Custom_Command + true + Enable Sleep States + hutch + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + hutch + oai-enb + - diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml index aafcdff6ea..5e3b64e01b 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml @@ -23,122 +23,115 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml --> - test-fdd-10-cdrx-tm1 - Test-FDD-10MHz-CDRX-TM1 - tasks - -100000 -111110 -040101 -800813 -030112 -040301 040302 040512 040612 040650 040401 -040201 -030212 -200000 -222222 - - + test-fdd-10-cdrx-tm1 + Test-FDD-10MHz-CDRX-TM1 + tasks - - Pull_Local_Registry - Pull Images from Local Registry - hutch - oai-enb - - - Custom_Command - Disable Sleep States - hutch - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - hutch - sudo cpupower idle-set -E - - - Create_Workspace - Create new Workspace for server 0 - hutch - - - Deploy_Object - Deploy eNB (FDD/Band7/10MHz/B200) in a container - hutch - ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_cdrx - + + Custom_Command + Disable Sleep States + hutch + sudo cpupower idle-set -D 0 + - - Undeploy_Object - true - Undeploy eNB - hutch - ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_cdrx - + + Pull_Local_Registry + Pull Images from Local Registry + hutch + oai-enb + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UE - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UE - adb_ue_1 adb_ue_2 - + + Initialize_UE + Initialize UE + adb_ue_1 adb_ue_2 + - - Ping - ping (10MHz - 20 sec) - -c 20 - 5 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Create_Workspace + Create new Workspace for server 0 + hutch + - - Iperf - iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile) - -u -b 30M -t 30 -R - 50 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Deploy_Object + Deploy eNB (FDD/Band7/10MHz/B200) in a container + hutch + ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_cdrx + - - Iperf - iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile) - -u -b 20M -t 30 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Attach_UE + Attach UE + adb_ue_1 adb_ue_2 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - hutch - oai-enb - + + Ping + ping (10MHz - 20 sec) + -c 20 + 5 + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Iperf + iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile) + -u -b 30M -t 30 -R + 50 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Iperf + iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile) + -u -b 20M -t 30 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Detach_UE + true + Detach UE + adb_ue_1 adb_ue_2 + + + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + + + + Undeploy_Object + true + Undeploy eNB + hutch + ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_cdrx + + + + Custom_Command + true + Enable Sleep States + hutch + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + hutch + oai-enb + - diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml index f50330ab89..5133c17f14 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml @@ -21,180 +21,164 @@ --> - test-fdd-10-tm1 - Test-FDD-10MHz-TM1 - tasks - -100000 -100001 -111110 -111111 -800813 -030111 -000001 -800814 -030311 -000002 -040511 040613 040616 040651 -030411 -000001 -030211 -200000 -200001 -222222 -333333 - - + test-fdd-10-tm1 + Test-FDD-10MHz-TM1 + tasks - - Pull_Local_Registry - Pull Images from Local Registry - hutch - oai-enb - - - Pull_Local_Registry - Pull Images from Local Registry - carabe - oai-lte-ue - - - Custom_Command - Disable Sleep States (hutch) - hutch - sudo cpupower idle-set -D 0 - - - Custom_Command - Disable Sleep States (carabe) - carabe - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States (hutch) - hutch - sudo cpupower idle-set -E - - - Custom_Command - true - Enable Sleep States (carabe) - carabe - sudo cpupower idle-set -E - - - Create_Workspace - Create new Workspace for server 0 - hutch - - - Deploy_Object - Deploy eNB (FDD/Band7/10MHz/B200) in a container - ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma - hutch - - - Create_Workspace - Create new Workspace for server 1 - carabe - - - Deploy_Object - Deploy LTE-UE (FDD/Band7/10MHz/B200) in a container - carabe - ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma - + + Custom_Command + Disable Sleep States (hutch) + hutch + sudo cpupower idle-set -D 0 + - - IdleSleep - Sleep - 5 - + + Custom_Command + Disable Sleep States (carabe) + carabe + sudo cpupower idle-set -D 0 + - - IdleSleep - Sleep - 10 - + + Pull_Local_Registry + Pull Images from Local Registry + hutch + oai-enb + - - Undeploy_Object - true - Undeploy eNB - hutch - ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma - + + Pull_Local_Registry + Pull Images from Local Registry + carabe + oai-lte-ue + - - Undeploy_Object - true - Undeploy LTE-UE - carabe - ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma - + + Create_Workspace + Create new Workspace for server 0 + hutch + - - Ping - ping (10MHz - 20 sec) - -c 20 - 5 - lte_oai_ue_carabe - nano-cn4g - + + Deploy_Object + Deploy eNB (FDD/Band7/10MHz/B200) in a container + ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma + hutch + - - Iperf - iperf (10MHz - DL/10Mbps/UDP)(30 sec)(balanced profile) - -u -b 10M -t 30 -R - 50 - lte_oai_ue_carabe - nano-cn4g - + + IdleSleep + Sleep + 5 + - - Iperf - iperf (10MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -R - 50 - lte_oai_ue_carabe - nano-cn4g - + + Create_Workspace + Create new Workspace for server 1 + carabe + - - Iperf - iperf (10MHz - UL/10Mbps/UDP)(30 sec)(balanced profile) - -u -b 10M -t 30 - 50 - lte_oai_ue_carabe - nano-cn4g - + + Deploy_Object + Deploy LTE-UE (FDD/Band7/10MHz/B200) in a container + carabe + ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma + - - Iperf - iperf (10MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 - 50 - balanced - lte_oai_ue_carabe - nano-cn4g - + + IdleSleep + Sleep + 10 + - - Clean_Test_Server_Images - true - Clean Test Images on eNB Test Server - hutch - oai-enb - + + Ping + ping (10MHz - 20 sec) + -c 20 + 5 + lte_oai_ue_carabe + nano-cn4g + - - Clean_Test_Server_Images - true - Clean Test Images on LTE-UE Test Server - carabe - oai-lte-ue - + + Iperf + iperf (10MHz - DL/10Mbps/UDP)(30 sec)(balanced profile) + -u -b 10M -t 30 -R + 50 + lte_oai_ue_carabe + nano-cn4g + + + + Iperf + iperf (10MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -R + 50 + lte_oai_ue_carabe + nano-cn4g + + + + Iperf + iperf (10MHz - UL/10Mbps/UDP)(30 sec)(balanced profile) + -u -b 10M -t 30 + 50 + lte_oai_ue_carabe + nano-cn4g + + + + Undeploy_Object + true + Undeploy LTE-UE + carabe + ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma + + + + IdleSleep + Sleep + 5 + + + + Undeploy_Object + true + Undeploy eNB + hutch + ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma + + + + Custom_Command + true + Enable Sleep States (hutch) + hutch + sudo cpupower idle-set -E + + + + Custom_Command + true + Enable Sleep States (carabe) + carabe + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on eNB Test Server + hutch + oai-enb + + + + Clean_Test_Server_Images + true + Clean Test Images on LTE-UE Test Server + carabe + oai-lte-ue + diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml index 52dbcb8972..cf092b2653 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml @@ -23,190 +23,139 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml --> - test-fdd-20-tm1 - Test-FDD-20MHz-TM1 - tasks - -100000 -111110 -040101 -800813 -030121 -000001 -040301 040521 040623 040624 040625 040662 040401 040201 -030221 -200000 -222222 - - + test-fdd-20-tm1 + Test-FDD-20MHz-TM1 + tasks - - Pull_Local_Registry - Pull Images from Local Registry - hutch - oai-enb - - - Custom_Command - Disable Sleep States - hutch - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - hutch - sudo cpupower idle-set -E - - - Create_Workspace - Create new Workspace for server 0 - hutch - - - Deploy_Object - Deploy eNB (FDD/Band7/20MHz/B200) in a container - hutch - ci-scripts/yaml_files/lte_b200_fdd_20Mhz_tm1 - + + Custom_Command + Disable Sleep States + hutch + sudo cpupower idle-set -D 0 + - - IdleSleep - Sleep - 5 - + + Pull_Local_Registry + Pull Images from Local Registry + hutch + oai-enb + - - Undeploy_Object - true - Undeploy eNB - hutch - ci-scripts/yaml_files/lte_b200_fdd_20Mhz_tm1 - + + Initialize_UE + Initialize UE + adb_ue_1 adb_ue_2 + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UE - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UE - adb_ue_1 adb_ue_2 - + + Create_Workspace + Create new Workspace for server 0 + hutch + - - Ping - ping (20MHz - 20 sec) - -c 20 - 5 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Deploy_Object + Deploy eNB (FDD/Band7/20MHz/B200) in a container + hutch + ci-scripts/yaml_files/lte_b200_fdd_20Mhz_tm1 + - - Iperf - iperf (20MHz - DL/70Mbps/UDP)(30 sec)(balanced profile) - -u -b 70M -t 30 -R - 50 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + IdleSleep + Sleep + 5 + - - Iperf - iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile) - -u -b 70M -t 30 -R - 50 - adb_ue_1 - ltebox-nano - + + Attach_UE + Attach UE + adb_ue_1 adb_ue_2 + - - Iperf - iperf (20MHz - DL/70Mbps/UDP)(30 sec)(unbalanced profile) - -u -b 70M -t 30 -R - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Ping + ping (20MHz - 20 sec) + -c 20 + 5 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -R - adb_ue_1 - ltebox-nano - + + Iperf + iperf (20MHz - DL/70Mbps/UDP)(30 sec)(balanced profile) + -u -b 70M -t 30 -R + 50 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - DL/TCP)(30 sec)(balanced profile) - -t 30 -R - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile) + -u -b 70M -t 30 -R + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (20MHz - UL/12Mbps/UDP)(30 sec)(balanced profile) - -u -b 12M -t 30 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (20MHz - DL/70Mbps/UDP)(30 sec)(unbalanced profile) + -u -b 70M -t 30 -R + 50 + unbalanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - UL/17Mbps/UDP)(30 sec)(single-ue profile) - -u -b 17M -t 30 - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (20MHz - UL/17Mbps/UDP)(30 sec)(single-ue profile) + -u -b 17M -t 30 + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (20MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 - adb_ue_1 - ltebox-nano - + + Detach_UE + true + Detach UE + adb_ue_1 adb_ue_2 + - - Iperf - iperf (20MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - hutch - oai-enb - + + Undeploy_Object + true + Undeploy eNB + hutch + ci-scripts/yaml_files/lte_b200_fdd_20Mhz_tm1 + + + + Custom_Command + true + Enable Sleep States + hutch + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + hutch + oai-enb + - diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml index f46697a106..849d6e0140 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml @@ -23,206 +23,193 @@ Replaces xml_files/enb_usrp210_band40_test_05mhz_tm1.xml --> - test-tdd-05-tm1 - Test-TDD-05MHz-TM1 - tasks - -300000 -100000 -111110 -040101 -800813 -030104 -040301 040501 040602 040601 040603 040604 040605 040642 040641 040643 040644 040645 040401 040201 -030204 -200000 -222222 - - + test-tdd-05-tm1 + Test-TDD-05MHz-TM1 + tasks - - Pull_Local_Registry - Pull Images from Local Registry - starsky - oai-enb - + + Custom_Command + Reset USRP + starsky + sudo -S b2xx_fx3_utils --reset-device + - - Custom_Command - Disable Sleep States - starsky - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - starsky - sudo cpupower idle-set -E - + + Custom_Command + Disable Sleep States + starsky + sudo cpupower idle-set -D 0 + - - Custom_Command - Reset USRP - starsky - sudo -S b2xx_fx3_utils --reset-device - - - Create_Workspace - Create new Workspace for server 0 - starsky - - - Deploy_Object - Deploy eNB (TDD/Band40/5MHz/B200) in a container - starsky - ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm1 - + + Pull_Local_Registry + Pull Images from Local Registry + starsky + oai-enb + - - IdleSleep - Sleep - 5 - + + Initialize_UE + Initialize UE + adb_ue_1 adb_ue_2 + - - Undeploy_Object - true - Undeploy eNB - starsky - ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm1 - + + Create_Workspace + Create new Workspace for server 0 + starsky + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UE - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UE - adb_ue_1 adb_ue_2 - + + Deploy_Object + Deploy eNB (TDD/Band40/5MHz/B200) in a container + starsky + ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm1 + - - Ping - ping (5MHz - 20 sec) - -c 20 - 25 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Attach_UE + Attach UE + adb_ue_1 adb_ue_2 + - - Iperf - iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced) - -u -b 6.5M -t 30 -R - 50 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Ping + ping (5MHz - 20 sec) + -c 20 + 25 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) - -u -b 6.5M -t 30 -R - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) + -u -b 6.5M -t 30 -R + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 6.5M -t 30 -R - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced) + -u -b 6.5M -t 30 -R + 50 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -R - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(unbalanced) + -u -b 6.5M -t 30 -R + 50 + unbalanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - DL/TCP)(30 sec) - -t 30 -R - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -R + adb_ue_1 + ltebox-nano + - - Iperf - iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - DL/TCP)(30 sec) + -t 30 -R + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) - -u -b 2M -t 30 - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) + -u -b 2M -t 30 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/TCP)(30 sec)(single-ue) - -t 30 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) + -u -b 2M -t 30 + 50 + unbalanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/TCP)(30 sec) - -t 30 - 50 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(single-ue) + -t 30 + adb_ue_1 + ltebox-nano + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - starsky - oai-enb - + + Iperf + iperf (5MHz - UL/TCP)(30 sec) + -t 30 + 50 + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Detach_UE + true + Detach UE + adb_ue_1 adb_ue_2 + + + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + + + + Undeploy_Object + true + Undeploy eNB + starsky + ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm1 + + + + Custom_Command + true + Enable Sleep States + starsky + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + starsky + oai-enb + diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml index da187e2120..3b2e5a8022 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml @@ -21,193 +21,175 @@ --> - test-tdd-05-if4-5 - Test-TDD-05MHz-TM1-IF4.5 - tasks - -300000 -100000 -111110 -800813 -030134 -030135 -040301 040532 040631 040632 040634 040635 040681 040682 040684 040685 040401 040201 -030231 -200000 -222222 - - + test-tdd-05-if4-5 + Test-TDD-05MHz-TM1-IF4.5 + tasks - - Pull_Local_Registry - Pull Images from Local Registry - starsky - oai-enb - + + Custom_Command + Reset USRP + starsky + sudo -S b2xx_fx3_utils --reset-device + - - Custom_Command - Disable Sleep States - starsky - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - starsky - sudo cpupower idle-set -E - + + Custom_Command + Disable Sleep States + starsky + sudo cpupower idle-set -D 0 + - - Custom_Command - Reset USRP - starsky - sudo -S b2xx_fx3_utils --reset-device - - - Create_Workspace - Create new Workspace for server 0 - starsky - - - Deploy_Object - Deploy RRU (TDD/Band40/5MHz/B200) in a container - starsky - ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5 - rru_tdd - - - Deploy_Object - Deploy RCC (TDD/Band40/5MHz) in a container - starsky - ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5 - rcc_tdd - + + Pull_Local_Registry + Pull Images from Local Registry + starsky + oai-enb + - - IdleSleep - Sleep - 5 - + + Create_Workspace + Create new Workspace for server 0 + starsky + - - Undeploy_Object - true - Undeploy RRU/RCC - starsky - ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5 - + + Deploy_Object + Deploy RRU (TDD/Band40/5MHz/B200) in a container + starsky + ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5 + rru_tdd + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UE - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UE - adb_ue_1 adb_ue_2 - + + Deploy_Object + Deploy RCC (TDD/Band40/5MHz) in a container + starsky + ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5 + rcc_tdd + - - Ping - ping (5MHz - 20 sec) - -c 20 - 25 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Attach_UE + Attach UE + adb_ue_1 adb_ue_2 + - - Iperf - iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced) - -u -b 6.5M -t 30 -R - 50 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Ping + ping (5MHz - 20 sec) + -c 20 + 25 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) - -u -b 6.5M -t 30 -R - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced) + -u -b 6.5M -t 30 -R + 50 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -R - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) + -u -b 6.5M -t 30 -R + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (5MHz - DL/TCP)(30 sec) - -t 30 -R - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -R + adb_ue_1 + ltebox-nano + - - Iperf - iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - DL/TCP)(30 sec) + -t 30 -R + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) + -u -b 2M -t 30 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (5MHz - UL/TCP)(30 sec)(single-ue) - -t 30 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (5MHz - UL/TCP)(30 sec) - -t 30 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(single-ue) + -t 30 + adb_ue_1 + ltebox-nano + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - starsky - oai-enb - + + Iperf + iperf (5MHz - UL/TCP)(30 sec) + -t 30 + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Detach_UE + true + Detach UE + adb_ue_1 adb_ue_2 + + + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + + + + Undeploy_Object + true + Undeploy RRU/RCC + starsky + ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5 + + + + Custom_Command + true + Enable Sleep States + starsky + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + starsky + oai-enb + diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml index 88b3330508..a947c6774c 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml @@ -23,197 +23,186 @@ Replaces xml_files/enb_usrp210_band40_test_10mhz_tm1.xml --> - test-tdd-10-tm1 - Test-TDD-10MHz-TM1 - tasks - -100000 -111110 -040101 -800813 -030114 -040301 040511 040612 040611 040613 040614 040615 040652 040651 040653 040654 040655 040401 040201 -030214 -200000 -222222 - - + test-tdd-10-tm1 + Test-TDD-10MHz-TM1 + tasks - - Pull_Local_Registry - Pull Images from Local Registry - starsky - oai-enb - - - Custom_Command - Disable Sleep States - starsky - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - starsky - sudo cpupower idle-set -E - - - Create_Workspace - Create new Workspace for server 0 - starsky - - - Deploy_Object - Deploy eNB (TDD/Band40/10MHz/B200) in a container - starsky - ci-scripts/yaml_files/lte_b200_tdd_10Mhz_tm1 - + + Custom_Command + Disable Sleep States + starsky + sudo cpupower idle-set -D 0 + - - IdleSleep - Sleep - 5 - + + Pull_Local_Registry + Pull Images from Local Registry + starsky + oai-enb + - - Undeploy_Object - true - Undeploy eNB - starsky - ci-scripts/yaml_files/lte_b200_tdd_10Mhz_tm1 - + + Initialize_UE + Initialize UE + adb_ue_1 adb_ue_2 + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UE - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UE - adb_ue_1 adb_ue_2 - + + Create_Workspace + Create new Workspace for server 0 + starsky + - - Ping - ping (10MHz - 20 sec) - -c 20 - 25 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Deploy_Object + Deploy eNB (TDD/Band40/10MHz/B200) in a container + starsky + ci-scripts/yaml_files/lte_b200_tdd_10Mhz_tm1 + - - Iperf - iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced) - -u -b 13.5M -t 30 -R - 50 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Attach_UE + Attach UE + adb_ue_1 adb_ue_2 + - - Iperf - iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) - -u -b 13.5M -t 30 -R - 50 - adb_ue_1 - ltebox-nano - + + Ping + ping (10MHz - 20 sec) + -c 20 + 25 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 13.5M -t 30 -R - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) + -u -b 13.5M -t 30 -R + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (10MHz - DL/TCP)(30 sec)(single-ue) - -t 30 -R - adb_ue_1 - ltebox-nano - + + Iperf + iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced) + -u -b 13.5M -t 30 -R + 50 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (10MHz - DL/TCP)(30 sec) - -t 30 -R - 50 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced) + -u -b 13.5M -t 30 -R + 50 + unbalanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (10MHz - DL/TCP)(30 sec)(single-ue) + -t 30 -R + adb_ue_1 + ltebox-nano + - - Iperf - iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (10MHz - DL/TCP)(30 sec) + -t 30 -R + 50 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (10MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) - -u -b 2M -t 30 - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (10MHz - UL/TCP)(30 sec)(single-ue) - -t 30 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced) + -u -b 2M -t 30 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (10MHz - UL/TCP)(30 sec) - -t 30 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (10MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) + -u -b 2M -t 30 + 50 + unbalanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - starsky - oai-enb - + + Iperf + iperf (10MHz - UL/TCP)(30 sec)(single-ue) + -t 30 + adb_ue_1 + ltebox-nano + + + + Iperf + iperf (10MHz - UL/TCP)(30 sec) + -t 30 + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Detach_UE + true + Detach UE + adb_ue_1 adb_ue_2 + + + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + + + + Undeploy_Object + true + Undeploy eNB + starsky + ci-scripts/yaml_files/lte_b200_tdd_10Mhz_tm1 + + + + Custom_Command + true + Enable Sleep States + starsky + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + starsky + oai-enb + diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml index 65f4dfc6b4..0888891cb3 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml @@ -23,195 +23,132 @@ Replaces xml_files/enb_usrp210_band40_test_20mhz_tm1.xml --> - test-tdd-20-tm1 - Test-TDD-20MHz-TM1 - tasks - -100000 -111110 -040101 -800813 -030124 -040301 040521 040622 040621 040623 040662 040401 040201 -030224 -200000 -222222 - - + test-tdd-20-tm1 + Test-TDD-20MHz-TM1 + tasks - - Pull_Local_Registry - Pull Images from Local Registry - starsky - oai-enb - - - Custom_Command - Disable Sleep States - starsky - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - starsky - sudo cpupower idle-set -E - - - Create_Workspace - Create new Workspace for server 0 - starsky - - - Deploy_Object - Deploy eNB (TDD/Band40/20MHz/B200) in a container - starsky - ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1 - + + Custom_Command + Disable Sleep States + starsky + sudo cpupower idle-set -D 0 + - - IdleSleep - Sleep - 5 - + + Pull_Local_Registry + Pull Images from Local Registry + starsky + oai-enb + - - Undeploy_Object - true - Undeploy eNB - starsky - ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1 - + + Initialize_UE + Initialize UE + adb_ue_1 adb_ue_2 + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UE - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UE - adb_ue_1 adb_ue_2 - + + Create_Workspace + Create new Workspace for server 0 + starsky + - - Ping - ping (20MHz - 20 sec) - -c 20 - 25 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Deploy_Object + Deploy eNB (TDD/Band40/20MHz/B200) in a container + starsky + ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1 + - - Iperf - iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(balanced) - -u -b 13.5M -t 30 -R - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Attach_UE + Attach UE + adb_ue_1 adb_ue_2 + - - Iperf - iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) - -u -b 13.5M -t 30 -R - 50 - adb_ue_1 - ltebox-nano - + + Ping + ping (20MHz - 20 sec) + -c 20 + 25 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 13.5M -t 30 -R - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) + -u -b 13.5M -t 30 -R + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (20MHz - DL/TCP)(30 sec)(single-ue) - -t 30 -R - adb_ue_1 - ltebox-nano - + + Iperf + iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(balanced) + -u -b 13.5M -t 30 -R + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - DL/TCP)(30 sec) - -t 30 -R - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced) + -u -b 13.5M -t 30 -R + 50 + unbalanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 -R - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (20MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 -R + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (20MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -R - 50 - adb_ue_1 - ltebox-nano - + + Detach_UE + true + Detach UE + adb_ue_1 adb_ue_2 + - - Iperf - iperf (20MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) - -u -b 2M -t 30 - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + - - Iperf - iperf (20MHz - UL/TCP)(30 sec)(single-ue) - -t 30 - adb_ue_1 - ltebox-nano - + + Undeploy_Object + true + Undeploy eNB + starsky + ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1 + - - Iperf - iperf (20MHz - UL/TCP)(30 sec) - -t 30 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Custom_Command + true + Enable Sleep States + starsky + sudo cpupower idle-set -E + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - starsky - oai-enb - + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + starsky + oai-enb + diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml index 6a0cb0f892..636abb1a66 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml @@ -23,200 +23,188 @@ Replaces xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml --> - test-tdd-20-tm1-def-sched - Test-TDD-20MHz-TM1-Default-Scheduler - tasks - -100000 -111110 -040101 -800813 -030125 -040301 040522 040627 040626 040628 040629 040630 040667 040666 040668 040669 040670 040401 040201 -030225 -200000 -222222 - - + test-tdd-20-tm1-def-sched + Test-TDD-20MHz-TM1-Default-Scheduler + tasks - - Pull_Local_Registry - Pull Images from Local Registry - starsky - oai-enb - + + Custom_Command + Disable Sleep States + starsky + sudo cpupower idle-set -D 0 + - - Custom_Command - Disable Sleep States - starsky - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - starsky - sudo cpupower idle-set -E - - - Create_Workspace - Create new Workspace for server 0 - starsky - - - Deploy_Object - Deploy eNB (TDD/Band40/20MHz/B200) in a container - starsky - ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1_default_scheduler - + + Pull_Local_Registry + Pull Images from Local Registry + starsky + oai-enb + - - IdleSleep - Sleep - 5 - + + Initialize_UE + Initialize UE + adb_ue_1 adb_ue_2 + - - Undeploy_Object - true - Undeploy eNB - starsky - ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1_default_scheduler - + + Create_Workspace + Create new Workspace for server 0 + starsky + - - Initialize_UE - Initialize UE - adb_ue_1 adb_ue_2 - - - Terminate_UE - true - Terminate UE - adb_ue_1 adb_ue_2 - - - Attach_UE - Attach UE - adb_ue_1 adb_ue_2 - - - Detach_UE - true - Detach UE - adb_ue_1 adb_ue_2 - + + Deploy_Object + Deploy eNB (TDD/Band40/20MHz/B200) in a container + starsky + ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1_default_scheduler + - - Ping - ping (20MHz - 20 sec) - -c 20 - 25 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Attach_UE + Attach UE + adb_ue_1 adb_ue_2 + - - Iperf - iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(balanced) - -u -b 27.5M -t 30 -R - 50 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Ping + ping (20MHz - 20 sec) + -c 20 + 25 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(single-ue) - -u -b 27.5M -t 30 -R - 50 - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(single-ue) + -u -b 27.5M -t 30 -R + 50 + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 27.5M -t 30 -R - 50 - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(balanced) + -u -b 27.5M -t 30 -R + 50 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - DL/TCP)(30 sec)(single-ue) - -t 30 -R - adb_ue_1 - ltebox-nano - + + Iperf + iperf (20MHz - DL/27.5Mbps/UDP)(30 sec)(unbalanced) + -u -b 27.5M -t 30 -R + 50 + 50 + unbalanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - DL/TCP)(30 sec) - -t 30 -R - 50 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (20MHz - DL/TCP)(30 sec)(single-ue) + -t 30 -R + adb_ue_1 + ltebox-nano + - - Iperf - iperf (20MHz - UL/7Mbps/UDP)(30 sec)(balanced) - -u -b 7M -t 30 - 50 - balanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (20MHz - DL/TCP)(30 sec) + -t 30 -R + 50 + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - UL/7Mbps/UDP)(30 sec)(single-ue) - -u -b 7M -t 30 - 50 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (20MHz - UL/7Mbps/UDP)(30 sec)(single-ue) + -u -b 7M -t 30 + 50 + adb_ue_1 + ltebox-nano + - - Iperf - iperf (20MHz - UL/7Mbps/UDP)(30 sec)(unbalanced) - -u -b 7M -t 30 - 50 - unbalanced - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (20MHz - UL/7Mbps/UDP)(30 sec)(balanced) + -u -b 7M -t 30 + 50 + balanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - UL/TCP)(30 sec)(single-ue) - -t 30 - adb_ue_1 - ltebox-nano - + + Iperf + iperf (20MHz - UL/7Mbps/UDP)(30 sec)(unbalanced) + -u -b 7M -t 30 + 50 + unbalanced + adb_ue_1 adb_ue_2 + ltebox-nano + - - Iperf - iperf (20MHz - UL/TCP)(30 sec) - -t 30 - adb_ue_1 adb_ue_2 - ltebox-nano - + + Iperf + iperf (20MHz - UL/TCP)(30 sec)(single-ue) + -t 30 + adb_ue_1 + ltebox-nano + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - starsky - oai-enb - + + Iperf + iperf (20MHz - UL/TCP)(30 sec) + -t 30 + adb_ue_1 adb_ue_2 + ltebox-nano + + + + Detach_UE + true + Detach UE + adb_ue_1 adb_ue_2 + + + + Terminate_UE + true + Terminate UE + adb_ue_1 adb_ue_2 + + + + Undeploy_Object + true + Undeploy eNB + starsky + ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1_default_scheduler + + + + Custom_Command + true + Enable Sleep States + starsky + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + starsky + oai-enb + diff --git a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml index 3337bba999..39ac1a7df4 100644 --- a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml +++ b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml @@ -25,71 +25,54 @@ TEST-LTE-2x2-N3XX-TM12.6 Ghz TDD LTE 2x2 TM1tasks - -111111 -100000 -010010 -800833 -030101 -010001 -000001 -050000 -050001 -070000 -070001 -010010 -030201 -333333 - - - - - + Pull_Local_Registry Pull Images from Local Registry obelix oai-enb - + Custom_Command Disable Sleep States obelix sudo cpupower idle-set -D 0 - - Custom_Command - Enable Sleep States - obelix - sudo cpupower idle-set -E + + Detach_UE + true + Detach UE + up2 - + + Create_Workspace Create new Workspace obelix - + + Deploy_Object Deploy eNB (TDD/Band38/2.6Ghz/N3XX) in a container obelix ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm1 - - IdleSleep - Sleep - 5 - - - + Attach_UE Attach UE up2 - + + IdleSleep + Sleep + 5 + + + Ping Ping: 20 pings up2 @@ -99,7 +82,7 @@ 60 - + Ping Ping: 100 pings, size 1024 up2 @@ -107,9 +90,9 @@ -c 100 -s 1024 -i 0.2 1 60 - + - + Iperf iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile) -u -b 26M -t 60 -R @@ -117,44 +100,39 @@ porcepix-cn4g 5 95 - + - - Iperf - iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile) - -u -b 7M -t 60 - up2 - porcepix-cn4g - 5 - 95 - + + Iperf + iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile) + -u -b 7M -t 60 + up2 + porcepix-cn4g + 5 + 95 + - + Detach_UE true Detach UE up2 - + Undeploy_Object true Undeploy gNB obelix ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm1 - - - Clean_Test_Server_Images - true - Clean Test Images - obelix - oai-enb - + + Clean_Test_Server_Images + true + Clean Test Images + obelix + oai-enb + - diff --git a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml index a3e89df4a6..e2b9f7ae13 100644 --- a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml +++ b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml @@ -25,71 +25,54 @@ TEST-LTE-2x2-N3XXi-TM2 2.6 Ghz TDD LTE 2x2 TM2 tasks - -111111 -100000 -010010 -800833 -031101 -010001 -000001 -051000 -051001 -071000 -071001 -010010 -031201 -333333 - - - - - + Pull_Local_Registry Pull Images from Local Registry obelix oai-enb - + Custom_Command Disable Sleep States obelix sudo cpupower idle-set -D 0 - - Custom_Command - Enable Sleep States - obelix - sudo cpupower idle-set -E + + Detach_UE + true + Detach UE + up2 - + + Create_Workspace Create new Workspace obelix - + + Deploy_Object Deploy eNB (TDD/Band38/2.6Ghz/N3XX) in a container obelix ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2 - - IdleSleep - Sleep - 5 - - - + Attach_UE Attach UE up2 - + + IdleSleep + Sleep + 5 + + + Ping Ping: 20 pings up2 @@ -99,7 +82,7 @@ 60 - + Ping Ping: 100 pings, size 1024 up2 @@ -107,9 +90,9 @@ -c 100 -s 1024 -i 0.2 1 60 - + - + Iperf iperf (DL/26Mbps/UDP)(60 sec)(single-ue profile) -u -b 1M -t 60 -R @@ -117,45 +100,39 @@ porcepix-cn4g 5 95 - + - - Iperf - iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile) - -u -b 7M -t 60 - up2 - porcepix-cn4g - 5 - 95 - + + Iperf + iperf (UL/7Mbps/UDP)(60 sec)(single-ue profile) + -u -b 7M -t 60 + up2 + porcepix-cn4g + 5 + 95 + - + Detach_UE true Detach UE up2 - + Undeploy_Object true Undeploy gNB obelix ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2 - - - Clean_Test_Server_Images - true - Clean Test Images - obelix - oai-enb - - + + Clean_Test_Server_Images + true + Clean Test Images + obelix + oai-enb + - diff --git a/ci-scripts/xml_files/container_nsa_b200_quectel.xml b/ci-scripts/xml_files/container_nsa_b200_quectel.xml index c73c6dadca..a9e859886c 100644 --- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml @@ -21,261 +21,226 @@ --> - TEST-NSA-FR1-TM1-B200 - NSA SanityCheck with QUECTEL - tasks - - 200000 - 100000 - 500000 - 111110 - 111111 - 000100 - 010000 - 800833 - 030101 - 800834 - 030102 - 010001 - 050000 - 050001 - 070001 - 070000 - 070002 - 050002 - 050003 - 010010 - 010002 - 030202 - 030201 - 060000 - 300000 - 600000 - 222220 - 222221 - - + TEST-NSA-FR1-TM1-B200 + NSA SanityCheck with QUECTEL + tasks - - Pull_Local_Registry - Pull Images from Local Registry - nepes - oai-enb - + + Custom_Command + Disable Sleep States (nepes) + nepes + sudo cpupower idle-set -D 0 + - - Pull_Local_Registry - Pull Images from Local Registry - ofqot - oai-gnb - + + Custom_Command + Reset USRP on nepes + nepes + sudo -S /usr/local/lib/uhd/utils/b2xx_fx3_utils --reset-device + - - Custom_Command - Reset USRP on nepes - nepes - sudo -S /usr/local/lib/uhd/utils/b2xx_fx3_utils --reset-device - + + Custom_Command + Disable Sleep States (ofqot) + ofqot + sudo cpupower idle-set -D 0 + - - Custom_Command - Disable Sleep States (nepes) - nepes - sudo cpupower idle-set -D 0 - - - Custom_Command + + Pull_Local_Registry + Pull Images from Local Registry + nepes + oai-enb + + + + Pull_Local_Registry + Pull Images from Local Registry + ofqot + oai-gnb + + + + DeployCoreNetwork + Start EPC + ltebox-nepes + + + + Initialize_UE + Initialize Quectel + idefix + + + + Create_Workspace + Create new Workspace + nepes + + + + Deploy_Object + Deploy eNB (FDD/Band7/5MHz/B200) in a container + nepes + ci-scripts/yaml_files/nsa_b200_enb + + + + Create_Workspace + Create new Workspace + ofqot + + + + Deploy_Object + Deploy gNB (TDD/Band78/40MHz/B200) in a container + ofqot + ci-scripts/yaml_files/nsa_b200_gnb + + + + Attach_UE + Attach UE + idefix + + + + Ping + Ping: 20pings in 20sec + idefix + ltebox-nepes + -c 20 + 1 + 15 + + + + Ping + Ping: 100pings in 20sec + idefix + ltebox-nepes + -c 100 -i 0.2 + 1 + 15 + + + + Iperf + iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile) + -u -b 8M -t 60 + idefix + ltebox-nepes + 1 + 95 + + + + Iperf + iperf (DL/70Mbps/UDP)(60 sec)(single-ue profile) + -u -b 70M -t 60 -R + idefix + ltebox-nepes + 25 + 80 + + + + Iperf + iperf (BIDIR TCP)(10 sec)(single-ue profile) + -t 10 --bidir + idefix + ltebox-nepes + + + + Ping + Ping: 20pings in 20sec + idefix + ltebox-nepes + -c 20 + 1 + 15 + + + + Ping + Ping: 100pings in 20sec + idefix + ltebox-nepes + -c 100 -i 0.2 + 1 + 15 + + + + Detach_UE true - Enable Sleep States (nepes) - nepes - sudo cpupower idle-set -E - - - Custom_Command - Disable Sleep States (ofqot) - ofqot - sudo cpupower idle-set -D 0 - - - Custom_Command + Detach UE + idefix + + + + Terminate_UE true - Enable Sleep States (ofqot) - ofqot - sudo cpupower idle-set -E - + Terminate Quectel + idefix + - - DeployCoreNetwork - Start EPC - ltebox-nepes - - - - Initialize_UE - Initialize Quectel - idefix - - - Terminate_UE + + Undeploy_Object true - Terminate Quectel - idefix - - - Attach_UE - Attach UE - idefix - - - Detach_UE + Undeploy gNB + ofqot + ci-scripts/yaml_files/nsa_b200_gnb + 10,100,100,100 + 10,100,100,100 + + + + Undeploy_Object true - Detach UE - idefix - - - Create_Workspace - Create new Workspace - nepes - - - Deploy_Object - Deploy eNB (FDD/Band7/5MHz/B200) in a container - nepes - ci-scripts/yaml_files/nsa_b200_enb - - - Create_Workspace - Create new Workspace - ofqot - - - Deploy_Object - Deploy gNB (TDD/Band78/40MHz/B200) in a container - ofqot - ci-scripts/yaml_files/nsa_b200_gnb - + Undeploy eNB + nepes + ci-scripts/yaml_files/nsa_b200_enb + - - IdleSleep - Sleep - 5 - - - - IdleSleep - Sleep - 20 - - - - - Ping - Ping: 20pings in 20sec - idefix - ltebox-nepes - -c 20 - 1 - 15 - - - - Ping - Ping: 100pings in 20sec - idefix - ltebox-nepes - -c 100 -i 0.2 - 1 - 15 - - - - Ping - Ping: 20pings in 20sec - idefix - ltebox-nepes - -c 20 - 1 - 15 - - - - Ping - Ping: 100pings in 20sec - idefix - ltebox-nepes - -c 100 -i 0.2 - 1 - 15 - - - - Iperf - iperf (DL/70Mbps/UDP)(60 sec)(single-ue profile) - -u -b 70M -t 60 -R - idefix - ltebox-nepes - 25 - 80 - - - - Iperf - iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile) - -u -b 8M -t 60 - idefix - ltebox-nepes - 1 - 95 - - - - Iperf - iperf (BIDIR TCP)(10 sec)(single-ue profile) - -t 10 --bidir - idefix - ltebox-nepes - - - - Undeploy_Object - true - Undeploy eNB - nepes - ci-scripts/yaml_files/nsa_b200_enb - - - - UndeployCoreNetwork - Terminate EPC - true - ltebox-nepes - - - - Undeploy_Object - true - Undeploy gNB - ofqot - ci-scripts/yaml_files/nsa_b200_gnb - 10,100,100,100 - 10,100,100,100 - - - - Clean_Test_Server_Images + + UndeployCoreNetwork + Terminate EPC true - Clean Test Images on Test Server - nepes - oai-enb - + ltebox-nepes + - - Clean_Test_Server_Images + + Custom_Command true - Clean Test Images on Test Server - ofqot - oai-gnb - + Enable Sleep States (nepes) + nepes + sudo cpupower idle-set -E + + + + Custom_Command + true + Enable Sleep States (ofqot) + ofqot + sudo cpupower idle-set -E + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + nepes + oai-enb + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + ofqot + oai-gnb + - diff --git a/ci-scripts/xml_files/container_sa_aerial_cn_start.xml b/ci-scripts/xml_files/container_sa_aerial_cn_start.xml index db622423ae..e29a8aa781 100644 --- a/ci-scripts/xml_files/container_sa_aerial_cn_start.xml +++ b/ci-scripts/xml_files/container_sa_aerial_cn_start.xml @@ -21,17 +21,14 @@ --> - TEST-AERIAL-SA-CN-START - Deploy 5GC - tasks - - 555000 - - - - DeployCoreNetwork - Initialize 5G Core - oc-cn5g-20897-aerial - - + TEST-AERIAL-SA-CN-START + Deploy 5GC + tasks + + DeployCoreNetwork + Initialize 5G Core + oc-cn5g-20897-aerial + + + diff --git a/ci-scripts/xml_files/container_sa_aerial_cn_stop.xml b/ci-scripts/xml_files/container_sa_aerial_cn_stop.xml index bf0bd9fb9c..f50c07a41f 100644 --- a/ci-scripts/xml_files/container_sa_aerial_cn_stop.xml +++ b/ci-scripts/xml_files/container_sa_aerial_cn_stop.xml @@ -21,18 +21,15 @@ --> - TEST-AERIAL-SA-CN-STOP - Undeploy 5GC - tasks - - 000555 - - - - UndeployCoreNetwork - true - Terminate 5G Core - oc-cn5g-20897-aerial - - + TEST-AERIAL-SA-CN-STOP + Undeploy 5GC + tasks + + UndeployCoreNetwork + true + Terminate 5G Core + oc-cn5g-20897-aerial + + + diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel.xml b/ci-scripts/xml_files/container_sa_aerial_quectel.xml index bf3f702219..b5a2e11e50 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel.xml @@ -21,136 +21,127 @@ --> - TEST-AERIAL-SA - AERIAL 100 MHz TDD SA - tasks - - 111111 - 000222 - 800813 - 002222 - 002223 - 000111 - 000011 - 000022 - 000033 - 200022 - 300033 - 000222 - 222222 - 333333 - - - - Pull_Local_Registry - Pull Images from Local Registry - gracehopper1-oai - oai-gnb-aerial - arm_ - + TEST-AERIAL-SA + AERIAL 100 MHz TDD SA + tasks - - Create_Workspace - Create new Workspace for server 0 - gracehopper1-oai - + + Pull_Local_Registry + Pull Images from Local Registry + gracehopper1-oai + oai-gnb-aerial + arm_ + - - Deploy_Object - Deploy PNF/Nvidia CUBB in a container - gracehopper1-oai - ci-scripts/yaml_files/sa_gnb_aerial - nv-cubb - + + Detach_UE + true + Detach Quectel + up2-aerial + - - Deploy_Object - Deploy VNF in a container - gracehopper1-oai - ci-scripts/yaml_files/sa_gnb_aerial - oai-gnb-aerial - + + Create_Workspace + Create new Workspace for server 0 + gracehopper1-oai + - - Attach_UE - Attach Quectel - up2-aerial - + + Deploy_Object + Deploy PNF/Nvidia CUBB in a container + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial + nv-cubb + - - Ping - Ping: 100pings in 20sec - up2-aerial - oc-cn5g-20897-aerial - -c 100 -i 0.2 - 5 - + + Deploy_Object + Deploy VNF in a container + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial + oai-gnb-aerial + - - Iperf - iperf (DL/UDP/800M)(30 sec)(single-ue profile) - -u -b 800M -t 30 -R - oc-cn5g-20897-aerial - up2-aerial - 25 - 80 - + + Attach_UE + Attach Quectel + up2-aerial + - - Iperf - iperf (UL/UDP/150M)(30 sec)(single-ue profile) - -u -b 150M -t 30 -l 1428 - oc-cn5g-20897-aerial - up2-aerial - 25 - 80 - + + Ping + Ping: 100pings in 20sec + up2-aerial + oc-cn5g-20897-aerial + -c 100 -i 0.2 + 5 + - - Iperf - Optional iperf (DL/UDP/1000M)(30 sec)(single-ue profile) - true - -u -b 1000M -t 30 -R - oc-cn5g-20897-aerial - up2-aerial - 25 - 80 - + + Iperf + iperf (DL/UDP/800M)(30 sec)(single-ue profile) + -u -b 800M -t 30 -R + oc-cn5g-20897-aerial + up2-aerial + 25 + 80 + - - Iperf - Optional iperf (UL/UDP/200M)(30 sec)(single-ue profile) - true - -u -b 200M -t 30 -l 1428 - oc-cn5g-20897-aerial - up2-aerial - 25 - 80 - + + Iperf + iperf (UL/UDP/150M)(30 sec)(single-ue profile) + -u -b 150M -t 30 -l 1428 + oc-cn5g-20897-aerial + up2-aerial + 25 + 80 + - - Detach_UE - true - Detach Quectel - up2-aerial - + + Iperf + Optional iperf (DL/UDP/1000M)(30 sec)(single-ue profile) + true + -u -b 1000M -t 30 -R + oc-cn5g-20897-aerial + up2-aerial + 25 + 80 + - - Undeploy_Object - true - Undeploy gNB - gracehopper1-oai - ci-scripts/yaml_files/sa_gnb_aerial - 20,100,100,100 - 20,100,100,100 - + + Iperf + Optional iperf (UL/UDP/200M)(30 sec)(single-ue profile) + true + -u -b 200M -t 30 -l 1428 + oc-cn5g-20897-aerial + up2-aerial + 25 + 80 + + + + Detach_UE + true + Detach Quectel + up2-aerial + + + + Undeploy_Object + true + Undeploy gNB + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial + 20,100,100,100 + 20,100,100,100 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + gracehopper1-oai + oai-gnb-aerial + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - gracehopper1-oai - oai-gnb-aerial - - diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml b/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml index baf525f167..c577236887 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml @@ -21,124 +21,116 @@ --> - TEST-AERIAL-SA-UL-Heavy - AERIAL 100 MHz DSUUU SA - tasks - - 111111 - 000222 - 800813 - 002222 - 002223 - 000111 - 000011 - 000032 - 000033 - 000022 - 000222 - 222222 - 333333 - - - - Pull_Local_Registry - Pull Images from Local Registry - gracehopper1-oai - oai-gnb-aerial - arm_ - + TEST-AERIAL-SA-UL-Heavy + AERIAL 100 MHz DSUUU SA + tasks - - Create_Workspace - Create new Workspace for server 0 - gracehopper1-oai - + + Pull_Local_Registry + Pull Images from Local Registry + gracehopper1-oai + oai-gnb-aerial + arm_ + - - Deploy_Object - Deploy PNF/Nvidia CUBB in a container - gracehopper1-oai - ci-scripts/yaml_files/sa_gnb_aerial_ul - nv-cubb - + + Detach_UE + true + Detach Quectel + up2-aerial + - - Deploy_Object - Deploy VNF in a container - gracehopper1-oai - ci-scripts/yaml_files/sa_gnb_aerial_ul - oai-gnb-aerial - + + Create_Workspace + Create new Workspace for server 0 + gracehopper1-oai + - - Attach_UE - Attach Quectel - up2-aerial - + + Deploy_Object + Deploy PNF/Nvidia CUBB in a container + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial_ul + nv-cubb + - - Ping - Ping: 100pings in 20sec - up2-aerial - oc-cn5g-20897-aerial - -c 100 -i 0.2 - 5 - + + Deploy_Object + Deploy VNF in a container + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial_ul + oai-gnb-aerial + - - Iperf - iperf (DL/UDP/200M)(30 sec)(single-ue profile) - -u -b 200M -t 30 -R - oc-cn5g-20897-aerial - up2-aerial - 25 - 80 - + + Attach_UE + Attach Quectel + up2-aerial + - - Iperf - iperf (UL/UDP/300M)(30 sec)(single-ue profile) - -u -b 300M -t 30 -l 1428 - oc-cn5g-20897-aerial - up2-aerial - 10 - 90 - + + Ping + Ping: 100pings in 20sec + up2-aerial + oc-cn5g-20897-aerial + -c 100 -i 0.2 + 5 + - - Iperf - iperf (UL/UDP/380M)(30 sec)(single-ue profile) - true - -u -b 380M -t 30 -l 1428 - oc-cn5g-20897-aerial - up2-aerial - 10 - 90 - + + Iperf + iperf (UL/UDP/300M)(30 sec)(single-ue profile) + -u -b 300M -t 30 -l 1428 + oc-cn5g-20897-aerial + up2-aerial + 10 + 90 + - - Detach_UE - true - Detach Quectel - up2-aerial - + + Iperf + iperf (UL/UDP/380M)(30 sec)(single-ue profile) + true + -u -b 380M -t 30 -l 1428 + oc-cn5g-20897-aerial + up2-aerial + 10 + 90 + - - Undeploy_Object - true - Undeploy gNB - gracehopper1-oai - ci-scripts/yaml_files/sa_gnb_aerial_ul - 20,100,100,100 - 20,100,100,100 - + + Iperf + iperf (DL/UDP/200M)(30 sec)(single-ue profile) + -u -b 200M -t 30 -R + oc-cn5g-20897-aerial + up2-aerial + 25 + 80 + + + + Detach_UE + true + Detach Quectel + up2-aerial + + + + Undeploy_Object + true + Undeploy gNB + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial_ul + 20,100,100,100 + 20,100,100,100 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + gracehopper1-oai + oai-gnb-aerial + - - Clean_Test_Server_Images - true - Clean Test Images on Test Server - gracehopper1-oai - oai-gnb-aerial - - diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue.xml index e5d32c181f..6dfbc83187 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue.xml @@ -24,34 +24,8 @@ TEST-5G-AW2S 20 MHz TDD SA tasks - 1 - - 110000 - 101000 - 100813 - 120000 - 102000 - 102001 - 302001 - 102002 - 302002 - 102003 - 100100 - 100010 - 100020 - 100030 - 100040 - 102016 - 100200 - 103000 - 104000 - 100002 - 130000 - 444444 - - - + Pull_Cluster_Image Pull Images from Cluster oaicicd-ran @@ -59,58 +33,68 @@ avra - + Initialize_UE Initialize Amarisoft UE amarisoft_ue - + Create_Workspace Creating new Workspace avra - + Deploy_Object Deploy gNB (TDD/Band78/20MHz/aw2s) in a container avra ci-scripts/yaml_files/sa_aw2s_gnb - + Attach_UE Attach UE 1 amarisoft_ue_1 - + Custom_Command Verify UE 1 is normal (no RedCap) avra [ $(docker logs oai-gnb-aw2s | grep -E "UE with RNTI [0-9a-f]{4} is RedCap" | wc -l) -eq 0 ] - + Attach_UE Attach (RedCap) UE 2 amarisoft_ue_2 - + Custom_Command Verify UE 2 is RedCap avra [ $(docker logs oai-gnb-aw2s | grep -m1 -E "UE with RNTI [0-9a-f]{4} is RedCap" | wc -l) -eq 1 ] - + Attach_UE Attach UE 3 - 15 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 - + + Ping + Ping: 50 pings in 10sec, multi-ue + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + oc-cn5g + -c 50 -i 0.2 + 5 + 25 + + + Iperf iperf (DL/3Mbps/UDP)(30 sec) -u -b 45M -t 30 -R @@ -121,16 +105,7 @@ oc-cn5g - - Iperf - iperf (DL/TCP)(30 sec) - -t 30 -R - amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 - 2 - oc-cn5g - - - + Iperf iperf (UL/1Mbps/UDP)(30 sec) -u -b 15M -t 30 @@ -141,7 +116,16 @@ oc-cn5g - + + Iperf + iperf (DL/TCP)(30 sec) + -t 30 -R + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + 2 + oc-cn5g + + + Iperf iperf (UL/TCP)(30 sec) -t 30 @@ -151,23 +135,13 @@ oc-cn5g - - Ping - Ping: 50 pings in 10sec, multi-ue - amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 - oc-cn5g - -c 50 -i 0.2 - 5 - 25 - - - + Attach_UE Attach (RedCap) UE 16 amarisoft_ue_16 - + Ping Ping: 50pings in 10sec, multi-ue amarisoft_ue_16 @@ -177,27 +151,27 @@ 30 - + Detach_UE true Detach UE amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 amarisoft_ue_16 - + Terminate_UE true Terminate UE amarisoft_ue - + IdleSleep Sleep 5 - + Undeploy_Object true Undeploy gNB @@ -205,7 +179,7 @@ ci-scripts/yaml_files/sa_aw2s_gnb - + Clean_Test_Server_Images true Clean Test Images on Test Server diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml index 4a2dd6c420..c7e5ab5721 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml @@ -24,158 +24,135 @@ TEST-5G-2x2-AW2S 20 MHz TDD 2x2 SA tasks - - 010000 - 001000 - 800813 - 020000 - 002000 - 002001 - 002002 - 002003 - 002004 - 002005 - 002006 - 002007 - 002008 - 002009 - 002010 - 002011 - 002012 - 002013 - 002014 - 002015 - 000100 - 000010 - 000020 - 000030 - 000040 - 002016 - 000200 - 003000 - 004000 - 000002 - 030000 - 333333 - - - + Pull_Cluster_Image Pull Images from Cluster oaicicd-ran oai-gnb-aw2s avra - + + + Initialize_UE + Initialize Amarisoft UE + amarisoft_ue_2x2 + + + Create_Workspace Create new Workspace avra - + + Deploy_Object Deploy gNB (TDD/Band78/20MHz/aw2s) in a container avra ci-scripts/yaml_files/sa_aw2s_2x2_gnb - - Initialize_UE - Initialize Amarisoft UE - amarisoft_ue_2x2 - - - + Attach_UE Attach UE amarisoft_ue_1 - + Attach_UE Attach UE amarisoft_ue_2 - + Attach_UE Attach UE amarisoft_ue_3 - + Attach_UE Attach UE amarisoft_ue_4 - + Attach_UE Attach UE amarisoft_ue_5 - + Attach_UE Attach UE amarisoft_ue_6 - + Attach_UE Attach UE amarisoft_ue_7 - + Attach_UE Attach UE amarisoft_ue_8 - + Attach_UE Attach UE amarisoft_ue_9 - + Attach_UE Attach UE amarisoft_ue_10 - + Attach_UE Attach UE amarisoft_ue_11 - + Attach_UE Attach UE amarisoft_ue_12 - + Attach_UE Attach UE amarisoft_ue_13 - + Attach_UE Attach UE amarisoft_ue_14 - + Attach_UE Attach UE amarisoft_ue_15 - + + Ping + Ping: 20pings in 20sec, multi-ue + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + oc-cn5g + -c 20 + 5 + 25 + + + Iperf iperf (DL/4Mbps/UDP)(30 sec) -u -b 60M -t 30 -R @@ -186,16 +163,7 @@ oc-cn5g - - Iperf - iperf (DL/TCP)(30 sec) - -t 30 -R - amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 - 3.9 - oc-cn5g - - - + Iperf iperf (UL/1.5Mbps/UDP)(30 sec) -u -b 22.5M -t 30 @@ -206,7 +174,16 @@ oc-cn5g - + + Iperf + iperf (DL/TCP)(30 sec) + -t 30 -R + amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 + 3.9 + oc-cn5g + + + Iperf iperf (UL/TCP)(30 sec) -t 30 @@ -216,23 +193,13 @@ oc-cn5g - - Ping - Ping: 20pings in 20sec, multi-ue - amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 - oc-cn5g - -c 20 - 5 - 25 - - - + Attach_UE Attach UE amarisoft_ue_16 - + Ping Ping: 50pings in 10sec, multi-ue amarisoft_ue_16 @@ -242,27 +209,27 @@ 30 - + Detach_UE true Detach UE amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 amarisoft_ue_16 - + Terminate_UE true Terminate UE amarisoft_ue_2x2 - + IdleSleep Sleep 5 - + Undeploy_Object true Undeploy gNB @@ -270,7 +237,7 @@ ci-scripts/yaml_files/sa_aw2s_2x2_gnb - + Clean_Test_Server_Images true Clean Test Images on Test Server diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml index 7b42e42b0c..cb64146091 100644 --- a/ci-scripts/xml_files/container_sa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml @@ -24,110 +24,47 @@ TEST-SA-FR1-B200 20 MHz TDD SA tasks - - 100000 - 111111 - 010000 - 800813 - 030101 - 010001 - 050000 - 050001 - 070000 - 070001 - 070002 - 070003 - 070004 - 060001 - 000002 - 060002 - 050000 - 010010 - 010001 - 050001 - 010010 - 010001 - 050000 - 010010 - 010002 - 030201 - 200000 - 222222 - - - + + Custom_Command + Disable Sleep States + ofqot + sudo cpupower idle-set -D 0 + + + Pull_Local_Registry Pull Images from Local Registry ofqot oai-gnb - - Custom_Command - Disable Sleep States - ofqot - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - ofqot - sudo cpupower idle-set -E - - - + Initialize_UE Initialize Quectel idefix - - Terminate_UE - true - Terminate Quectel - idefix - - - Attach_UE - Attach UE - idefix - - - Detach_UE - true - Detach UE - idefix - - + + Create_Workspace Create new Workspace for server 0 ofqot - + + Deploy_Object Deploy gNB (TDD/Band78/40MHz/B200) in a container ofqot ci-scripts/yaml_files/sa_b200_gnb - - IdleSleep - Sleep - 5 - - - - Ping - Ping: 20pings + + Attach_UE + Attach UE idefix - sabox-nepes - -c 20 -i0.5 -w25 - 80 - - + Ping Ping: 20pings in 20sec idefix @@ -137,7 +74,7 @@ 15 - + Ping Ping: 100pings in 20sec idefix @@ -147,7 +84,7 @@ 15 - + Iperf iperf (DL/30Mbps/UDP)(30 sec)(single-ue profile) -u -b 30M -t 30 -R @@ -157,7 +94,7 @@ 80 - + Iperf iperf (UL/3.5Mbps/UDP)(30 sec)(single-ue profile) -u -b 3.5M -t 30 @@ -167,7 +104,7 @@ 95 - + Iperf iperf (BIDIR TCP)(10 sec)(single-ue profile) -t 10 --bidir @@ -175,7 +112,7 @@ sabox-nepes - + Iperf iperf (DL/TCP)(30 sec)(single-ue profile) -t 30 -R @@ -184,7 +121,7 @@ 40 - + Iperf iperf (UL/TCP)(30 sec)(single-ue profile) -t 30 @@ -193,20 +130,100 @@ 10 - + Custom_Command Trigger Reestablishment ofqot echo ci force_reestab | nc -N 127.0.0.1 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' - + + + Ping + Ping: 20pings + idefix + sabox-nepes + -c 20 -i0.5 -w25 + 80 + + + Custom_Command Verify Reestablishment ofqot echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' - + + Ping + Ping: 20pings in 20sec + idefix + sabox-nepes + -c 20 + 1 + 15 + + + + Detach_UE + true + Detach UE + idefix + + + + Attach_UE + Attach UE + idefix + + + + Ping + Ping: 100pings in 20sec + idefix + sabox-nepes + -c 100 -i 0.2 + 1 + 15 + + + + Detach_UE + true + Detach UE + idefix + + + + Attach_UE + Attach UE + idefix + + + + Ping + Ping: 20pings in 20sec + idefix + sabox-nepes + -c 20 + 1 + 15 + + + + Detach_UE + true + Detach UE + idefix + + + + Terminate_UE + true + Terminate Quectel + idefix + + + Undeploy_Object true Undeploy gNB @@ -216,7 +233,15 @@ 10,100,100,100 - + + Custom_Command + true + Enable Sleep States + ofqot + sudo cpupower idle-set -E + + + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -225,4 +250,3 @@ - diff --git a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml index 89a5ebfd6c..ce9e1121c3 100644 --- a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml @@ -24,105 +24,55 @@ TEST-SA-FR1-F1-E1-B200 40 MHz TDD F1+E1 SA tasks - - 333333 - 300000 - 310000 - 800813 - 330101 - 330102 - 330103 - 310001 - 400001 - 350000 - 370001 - 370000 - 370002 - 370003 - 370004 - 360001 - 100002 - 360002 - 350000 - 310011 - 310002 - 330201 - 200000 - 222222 - - - + Pull_Local_Registry Pull Images from Local Registry ofqot oai-gnb oai-nr-cuup - - Initialize_UE - Initialize Quectel - idefix - - - Terminate_UE - true - Terminate Quectel - idefix - - - Attach_UE - Attach Quectel - idefix - - - Detach_UE - true - Detach Quectel - idefix - - - Create_Workspace - Create new Workspace - ofqot - - - Deploy_Object - Deploy gNB-CU-CP in a container - ofqot - ci-scripts/yaml_files/sa_e1_b200_gnb - gnb_cucp - - - Deploy_Object - Deploy gNB-CU-UP in a container - ofqot - ci-scripts/yaml_files/sa_e1_b200_gnb - gnb_cuup - - - Deploy_Object - Deploy gNB-DU (TDD/Band78/40MHz/B200) in a container - ofqot - ci-scripts/yaml_files/sa_e1_b200_gnb - gnb_du_tdd - - - + Custom_Command Disable Sleep States ofqot sudo cpupower idle-set -D 0 - - Custom_Command - true - Enable Sleep States - ofqot - sudo cpupower idle-set -E + + + Initialize_UE + Initialize Quectel + idefix - + + Create_Workspace + Create new Workspace + ofqot + + + + Deploy_Object + Deploy gNB-CU-CP/gNB-CU-UP/gNB-DU (TDD/n76/40MHz/B200) + ofqot + ci-scripts/yaml_files/sa_e1_b200_gnb + gnb_cucp gnb_cuup gnb_du_tdd + + + + Attach_UE + Attach Quectel + idefix + + + + Custom_Command + Check UE is on dedicated BWP ID 1 + ofqot + echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 1 (dedicated) UL BWP ID 1 (dedicated)' + + + Ping Ping: 50pings in 10sec idefix @@ -132,73 +82,40 @@ 25 - + Iperf - iperf (DL/80Mbps/UDP)(30 sec) - -u -b 80M -t 30 -R + iperf (DL/TCP)(20 sec)(single-ue profile) + -t 20 -R idefix sabox-nepes - 10 - 95 + 140 - - Custom_Command - Check UE is on dedicated BWP ID 1 - ofqot - echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 1 (dedicated) UL BWP ID 1 (dedicated)' - - - + Iperf - iperf (UL/8Mbps/UDP)(30 sec) - -u -b 8M -t 30 - idefix - sabox-nepes - 1 - 95 - - - - Iperf - iperf (BIDIR TCP)(10 sec)(single-ue profile) - -t 20 --bidir - idefix - sabox-nepes - - - - Iperf - iperf (DL/TCP)(30 sec)(single-ue profile) - -t 30 -R - idefix - sabox-nepes - 30 - - - - Iperf - iperf (UL/TCP)(30 sec)(single-ue profile) - -t 30 + iperf (UL/TCP)(20 sec)(single-ue profile) + -t 20 idefix sabox-nepes 15 - + + Iperf + iperf (BIDIR TCP)(20 sec)(single-ue profile) + -t 20 --bidir + idefix + sabox-nepes + + + Custom_Command Trigger Reestablishment (on DU) ofqot echo ci force_reestab | nc -N 127.0.0.1 9091 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' - - Custom_Command - Verify Reestablishment (on CU) - ofqot - echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' - - + Ping Ping: 20pings idefix @@ -207,7 +124,132 @@ 80 - + + Custom_Command + Verify Reestablishment (on CU) + ofqot + echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' + + + + Ping + Ping: 50pings in 10sec + idefix + sabox-nepes + -c 20 -i 0.2 + 1 + 25 + + + + Custom_Command + Switch to dedicated BWP ID 2 + ofqot + echo ci trigger_bwp_switch 2 | nc -N 127.0.0.1 9091 | grep 'triggered BWP switch to BWP ID 2 for UE' + + + + Iperf + iperf (DL/TCP)(10 sec)(single-ue profile) + -t 10 -R + idefix + sabox-nepes + 35 + + + + Custom_Command + Check UE is on dedicated BWP ID 2 + ofqot + echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 2 (dedicated) UL BWP ID 2 (dedicated)' + + + + Custom_Command + Switch to dedicated BWP ID 3 + ofqot + echo ci trigger_bwp_switch 3 | nc -N 127.0.0.1 9091 | grep 'triggered BWP switch to BWP ID 3 for UE' + + + + Iperf + iperf (DL/TCP)(10 sec)(single-ue profile) + -t 10 -R + idefix + sabox-nepes + 65 + + + + Custom_Command + Check UE is on dedicated BWP ID 3 + ofqot + echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 3 (dedicated) UL BWP ID 3 (dedicated)' + + + + Custom_Command + Switch to initial BWP ID 0 + ofqot + echo ci trigger_bwp_switch 0 | nc -N 127.0.0.1 9091 | grep 'triggered BWP switch to BWP ID 0 for UE' + + + + Ping + Ping: 50pings in 10sec + idefix + sabox-nepes + -c 20 -i 0.2 + 1 + 25 + + + + Custom_Command + Check UE is on initial BWP ID 0 + ofqot + echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 0 (initial) UL BWP ID 0 (initial)' + + + + Custom_Command + Switch to dedicated BWP ID 1 + ofqot + echo ci trigger_bwp_switch 1 | nc -N 127.0.0.1 9091 | grep 'triggered BWP switch to BWP ID 1 for UE' + + + + Ping + Ping: 50pings in 10sec + idefix + sabox-nepes + -c 20 -i 0.2 + 1 + 25 + + + + Custom_Command + Check UE is on dedicated BWP ID 1 + ofqot + echo ci get_current_bwp | nc -N 127.0.0.1 9091 | grep 'DL BWP ID 1 (dedicated) UL BWP ID 1 (dedicated)' + + + + Detach_UE + true + Detach Quectel + idefix + + + + Terminate_UE + true + Terminate Quectel + idefix + + + Undeploy_Object true Undeploy CUCP/CU-UP/DU @@ -217,7 +259,15 @@ 10,100,100,100 - + + Custom_Command + true + Enable Sleep States + ofqot + sudo cpupower idle-set -E + + + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -226,4 +276,3 @@ - diff --git a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml index 3ae295597f..35103d01e7 100644 --- a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml @@ -24,85 +24,43 @@ TEST-SA-FR1-F1-B200 10 MHz FDD F1 SA tasks - - 111111 - 100000 - 110002 - 800813 - 130101 - 130102 - 100001 - 110000 - 110001 - 100001 - 150000 - 150001 - 110011 - 110001 - 150001 - 160001 - 100002 - 160002 - 150001 - 110011 - 110001 - 150000 - 170001 - 170000 - 170002 - 170003 - 170004 - 110011 - 110002 - 100001 - 130201 - 200000 - 222222 - - - + Pull_Local_Registry Pull Images from Local Registry ofqot oai-gnb - - Initialize_UE - Initialize Quectel - idefix + + Custom_Command + Disable Sleep States + ofqot + sudo cpupower idle-set -D 0 - + + Terminate_UE true Terminate Quectel idefix - - Attach_UE - Attach Quectel - idefix - - - Detach_UE - true - Detach Quectel - idefix - - + + Create_Workspace Create new Workspace ofqot - + + Deploy_Object Deploy gNB-CU in a container ofqot ci-scripts/yaml_files/sa_f1_b200_gnb gnb_cu - + + Deploy_Object Deploy gNB-DU (FDD/Band1/10MHz/B200) in a container ofqot @@ -110,36 +68,31 @@ gnb_du_fdd - - Custom_Command - Disable Sleep States - ofqot - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - ofqot - sudo cpupower idle-set -E - - - + IdleSleep Sleep 5 - - Ping - Ping: 20pings + + Initialize_UE + Initialize Quectel idefix - sabox-nepes - -c 20 -i0.5 -w25 - 80 - + + Attach_UE + Attach Quectel + idefix + + + + IdleSleep + Sleep + 5 + + + Ping Ping: 20pings in 20sec idefix @@ -149,7 +102,7 @@ 25 - + Ping Ping: 100pings in 20sec idefix @@ -159,37 +112,86 @@ 110 - + + Detach_UE + true + Detach Quectel + idefix + + + + Attach_UE + Attach Quectel + idefix + + + + Ping + Ping: 100pings in 20sec + idefix + sabox-nepes + -c 100 -i 0.2 + 1 + 110 + + + + Custom_Command + Trigger Reestablishment (on DU) + ofqot + echo ci force_reestab | nc -N 127.0.0.1 9091 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' + + + + Ping + Ping: 20pings + idefix + sabox-nepes + -c 20 -i0.5 -w25 + 80 + + + + Custom_Command + Verify Reestablishment (on CU) + ofqot + echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' + + + + Ping + Ping: 100pings in 20sec + idefix + sabox-nepes + -c 100 -i 0.2 + 1 + 110 + + + + Detach_UE + true + Detach Quectel + idefix + + + + Attach_UE + Attach Quectel + idefix + + + Ping Ping: 20pings in 20sec idefix sabox-nepes -c 20 1 - 110 + 25 - - Ping - Ping: 100pings in 20sec - idefix - sabox-nepes - -c 100 -i 0.2 - 1 - 110 - - - - Iperf - iperf (DL/50Mbps/UDP)(30 sec) - -u -b 50M -t 30 -R - idefix - sabox-nepes - 10 - 95 - - - + Iperf iperf (UL/25Mbps/UDP)(30 sec) -u -b 25M -t 30 @@ -199,7 +201,17 @@ 95 - + + Iperf + iperf (DL/50Mbps/UDP)(30 sec) + -u -b 50M -t 30 -R + idefix + sabox-nepes + 10 + 95 + + + Iperf iperf (BIDIR TCP)(60 sec)(single-ue profile) -t 60 --bidir @@ -207,7 +219,7 @@ sabox-nepes - + Iperf iperf (DL/TCP)(30 sec)(single-ue profile) -t 30 -R @@ -216,7 +228,7 @@ 45 - + Iperf iperf (UL/TCP)(30 sec)(single-ue profile) -t 30 @@ -225,20 +237,27 @@ 25 - - Custom_Command - Trigger Reestablishment (on DU) - ofqot - echo ci force_reestab | nc -N 127.0.0.1 9091 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' - - - Custom_Command - Verify Reestablishment (on CU) - ofqot - echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' + + Detach_UE + true + Detach Quectel + idefix - + + Terminate_UE + true + Terminate Quectel + idefix + + + + IdleSleep + Sleep + 5 + + + Undeploy_Object true Undeploy CU-DU @@ -248,7 +267,15 @@ 10,100,100,100 - + + Custom_Command + true + Enable Sleep States + ofqot + sudo cpupower idle-set -E + + + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -257,4 +284,3 @@ - diff --git a/ci-scripts/xml_files/container_sa_f1_ho_b210_quectel.xml b/ci-scripts/xml_files/container_sa_f1_ho_b210_quectel.xml index 07a5c5f401..ff36947a57 100644 --- a/ci-scripts/xml_files/container_sa_f1_ho_b210_quectel.xml +++ b/ci-scripts/xml_files/container_sa_f1_ho_b210_quectel.xml @@ -24,79 +24,47 @@ TEST-F1-HO-B210 F1 Handover 20 MHz TDD SA tasks - - 000001 - 000002 - 000003 - 000004 - 000005 - 000006 - 000007 - 000008 - 000009 - 000010 - 000011 - 000012 - 000013 - 000014 - 000015 - 000016 - 000017 - 000018 - 000019 - 000020 - 000021 - 000022 - 000023 - 000024 - 000025 - 000026 - 000027 - 000028 - - - - + DeployCoreNetwork Initialize 5G Core oc-cn5g-00103-ho - + Pull_Local_Registry Pull Images from Local Registry oai-gnb groot - + Pull_Local_Registry Pull Images from Local Registry oai-gnb rocket - + Create_Workspace Create new Workspace for groot groot - + Create_Workspace Create new Workspace on rocket rocket - + Custom_Command Set attenuator to 0 for DU0 and 17 for DU1 rocket python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1,2 0 -s 3,4 25 - + Deploy_Object Deploy gNB-CU in a container ci-scripts/yaml_files/5g_sa_f1_b210_ho @@ -104,7 +72,7 @@ oai-cu - + Deploy_Object Deploy gNB-DU0 (TDD/Band77/20MHz/B210) in a container ci-scripts/yaml_files/5g_sa_f1_b210_ho @@ -112,7 +80,7 @@ groot - + Deploy_Object Deploy gNB-DU1 (TDD/Band77/20MHz/B210) in a container ci-scripts/yaml_files/5g_sa_f1_b210_ho @@ -120,13 +88,13 @@ oai-du1 - + Attach_UE Attach Quectel raspix - + Ping Ping: 100pings in 20sec raspix @@ -135,20 +103,20 @@ 5 - + IdleSleep Sleep 5 - + Custom_Command Attenuate DU0 by 15 and remove the attenuation on DU1 to trigger Handover rocket python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 15 -r 3,4 0 -d 5 - + Ping Ping: 50pings in 10sec raspix @@ -157,21 +125,21 @@ 5 - + Custom_Command UE connected to DU1? groot echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3585" - - Custom_Command + + Custom_Command Attenuate DU1 by 17dB and remove attenuation on DU0 to trigger Handover rocket python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 0 -r 3,4 25 -d 5 - + Ping Ping: 50pings in 10sec raspix @@ -180,21 +148,21 @@ 5 - + Custom_Command UE connected to DU0? groot echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3584" - - Custom_Command + + Custom_Command Attenuate DU0 by 15 and remove the attenuation on DU1 to trigger Handover rocket python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 15 -r 3,4 0 -d 5 - + Ping Ping: 50pings in 10sec raspix @@ -203,21 +171,21 @@ 5 - + Custom_Command UE connected to DU1? groot echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3585" - + Detach_UE true Detach Quectel raspix - + Undeploy_Object true Undeploy CU-DU0 @@ -225,23 +193,23 @@ ci-scripts/yaml_files/5g_sa_f1_b210_ho - + Undeploy_Object true - Undeploy DU1 + Undeploy DU1 rocket ci-scripts/yaml_files/5g_sa_f1_b210_ho - - Custom_Command + + Custom_Command Reset all channels on the attenuator to 0 rocket python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1-4 0 true - + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -249,7 +217,7 @@ oai-gnb - + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -257,7 +225,7 @@ oai-gnb - + UndeployCoreNetwork true Terminate 5G Core @@ -265,4 +233,3 @@ - diff --git a/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml b/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml index 979aabbc5e..3129883744 100644 --- a/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml +++ b/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml @@ -24,60 +24,41 @@ test-5g-fhi72-metanoia-2x2 100 MHz TDD SA METANOIA tasks - - 200000 - 110000 - 800813 - 120000 - 102000 - 102001 - 100100 - 100010 - 100020 - 100030 - 100040 - 103000 - 100002 - 130000 - 777777 - 888888 - - - + Custom_Script Setup sriov and network interfaces Metanoia cacofonix - + Pull_Local_Registry Pull Images from Local Registry cacofonix oai-gnb-fhi72 - + Create_Workspace Create new Workspace for server 0 cacofonix - + Deploy_Object Deploy gNB (TDD/Band78/100MHz/Metanoia) in a container cacofonix ci-scripts/yaml_files/sa_fhi_7.2_metanoia_2x2_gnb - + Attach_UE Attach UE up2-fhi72 - + Ping Ping: 100 pings in 10 sec up2-fhi72 @@ -87,7 +68,7 @@ 15 - + Iperf iperf (DL/570Mbps/UDP)(30 sec) -u -b 570M -t 30 -R @@ -98,16 +79,7 @@ oc-cn5g-20897 - - Iperf - iperf (DL/TCP)(30 sec) - -t 30 -R - up2-fhi72 - 80 - oc-cn5g-20897 - - - + Iperf iperf (UL/100Mbps/UDP)(30 sec) -u -b 100M -t 30 @@ -118,7 +90,16 @@ oc-cn5g-20897 - + + Iperf + iperf (DL/TCP)(30 sec) + -t 30 -R + up2-fhi72 + 80 + oc-cn5g-20897 + + + Iperf iperf (UL/TCP)(30 sec) -t 30 @@ -127,20 +108,20 @@ oc-cn5g-20897 - + Detach_UE true Detach UE up2-fhi72 - + IdleSleep Sleep 5 - + Undeploy_Object true Undeploy gNB @@ -148,7 +129,7 @@ ci-scripts/yaml_files/sa_fhi_7.2_metanoia_2x2_gnb - + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -156,7 +137,7 @@ oai-gnb-fhi72 - + Custom_Script true Set CPU to idle state, set kernel parameters to default values diff --git a/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml b/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml index b8df43ef52..c02a12deac 100644 --- a/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml +++ b/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml @@ -24,59 +24,41 @@ test-5g-fhi72-vvdn 100 MHz TDD SA VVDN tasks - - 200000 - 110000 - 800813 - 120000 - 102000 - 102001 - 100100 - 100010 - 100020 - 100030 - 100040 - 100011 - 103000 - 100002 - 130000 - 777777 - 888888 - - - + Custom_Script Setup sriov and network interfaces VVDN cacofonix - + Pull_Local_Registry Pull Images from Local Registry cacofonix oai-gnb-fhi72 - + + Create_Workspace Create new Workspace for server 0 cacofonix - + + Deploy_Object Deploy gNB (TDD/Band78/100MHz/VVDN) in a container cacofonix ci-scripts/yaml_files/sa_fhi_7.2_vvdn_gnb - + Attach_UE Attach UE up2-fhi72 - + Ping Ping: 100 pings in 10 sec up2-fhi72 @@ -86,7 +68,7 @@ 15 - + Iperf iperf (DL/600Mbps/UDP)(30 sec) -u -b 600M -t 30 -R @@ -97,27 +79,7 @@ oc-cn5g-20897 - - Iperf - Optional iperf (DL/700Mbps/UDP)(30 sec) - true - -u -b 700M -t 30 -R - up2-fhi72 - 10 - 95 - oc-cn5g-20897 - - - - Iperf - iperf (DL/TCP)(30 sec) - -t 30 -R - up2-fhi72 - 40 - oc-cn5g-20897 - - - + Iperf iperf (UL/80Mbps/UDP)(30 sec) -u -b 80M -t 30 @@ -128,7 +90,16 @@ oc-cn5g-20897 - + + Iperf + iperf (DL/TCP)(30 sec) + -t 30 -R + up2-fhi72 + 40 + oc-cn5g-20897 + + + Iperf iperf (UL/TCP)(30 sec) -t 30 @@ -137,20 +108,31 @@ oc-cn5g-20897 - + + Iperf + Optional iperf (DL/700Mbps/UDP)(30 sec) + true + -u -b 700M -t 30 -R + up2-fhi72 + 10 + 95 + oc-cn5g-20897 + + + Detach_UE true Detach UE up2-fhi72 - + IdleSleep Sleep 5 - + Undeploy_Object true Undeploy gNB @@ -158,7 +140,7 @@ ci-scripts/yaml_files/sa_fhi_7.2_vvdn_gnb - + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -166,7 +148,7 @@ oai-gnb-fhi72 - + Custom_Script true Set CPU to idle state, set kernel parameters to default values @@ -174,5 +156,4 @@ - diff --git a/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml b/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml index 46707f70b4..84c5a5bea5 100644 --- a/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml +++ b/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml @@ -24,73 +24,47 @@ TEST-MONO-N2-HO-B210 Monolithic N2 Handover 20 MHz TDD SA tasks - - 000001 - 000002 - 000023 - 000003 - 000004 - 000005 - 000006 - 000007 - 000008 - 000009 - 000010 - 000011 - 000012 - 000013 - 000014 - 000015 - 000017 - 000018 - 000019 - 000016 - 000020 - 000021 - 000022 - - - - + + DeployCoreNetwork Initialize 5G Core oc-cn5g-00103-ho - + Pull_Local_Registry Pull Images from Local Registry oai-gnb groot - + Pull_Local_Registry Pull Images from Local Registry oai-gnb rocket - + Create_Workspace Create new Workspace for groot groot - - Create_Workspace - Create new Workspace on rocket - rocket - - - + Custom_Command Set initial attenuation on target gNB rocket python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1,2 0 -s 3,4 25 - + + Create_Workspace + Create new Workspace for rocket + rocket + + + Deploy_Object Deploy Monolithic gNB-PCI0 (TDD/Band77/20MHz/B210) in a container ci-scripts/yaml_files/5g_sa_n2_ho_b210 @@ -98,7 +72,7 @@ oai-gnb-pci0 - + Deploy_Object Deploy Monolithic gNB-PCI1 (TDD/Band77/20MHz/B210) in a container ci-scripts/yaml_files/5g_sa_n2_ho_b210 @@ -106,13 +80,13 @@ oai-gnb-pci1 - + Attach_UE Attach Quectel raspix - + Ping Ping: 100pings in 20sec raspix @@ -121,20 +95,20 @@ 5 - + IdleSleep Sleep 5 - + Custom_Command Gradually attenuate gNB-PCI0 (ch1-2=15dB) and gNB-PCI1 (ch3-4=0dB) over 5s to trigger N2 Handover to gNB-PCI1 rocket python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 15 -r 3,4 0 -d 5 - + Ping Ping: 50pings in 10sec raspix @@ -143,21 +117,21 @@ 5 - + Custom_Command UE connected to gNB-PCI1? rocket echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3585" - + Custom_Command Gradually attenuate gNB-PCI0 (ch1-2=0dB) and gNB-PCI1 (ch3-4=15dB) over 5s to trigger N2 Handover back to gNB-PCI0 rocket python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 0 -r 3,4 25 -d 5 - + Ping Ping: 50pings in 10sec raspix @@ -166,29 +140,21 @@ 5 - + Custom_Command UE connected to gNB-PCI0? groot echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3584" - - Custom_Command - true - Reset all attenuators to 0dB - rocket - python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1-4 0 - - - + Detach_UE true Detach Quectel raspix - + Undeploy_Object true Undeploy Monolithic gNB-PCI0 @@ -196,7 +162,7 @@ ci-scripts/yaml_files/5g_sa_n2_ho_b210 - + Undeploy_Object true Undeploy Monolithic gNB-PCI1 @@ -204,7 +170,15 @@ ci-scripts/yaml_files/5g_sa_n2_ho_b210 - + + Custom_Command + true + Reset all attenuators to 0dB + rocket + python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1-4 0 + + + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -212,7 +186,7 @@ oai-gnb - + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -220,7 +194,7 @@ oai-gnb - + UndeployCoreNetwork true Terminate 5G Core diff --git a/ci-scripts/xml_files/container_sa_n310_2X2_100MHz_quectel.xml b/ci-scripts/xml_files/container_sa_n310_2X2_100MHz_quectel.xml index ad98afcd32..0c3cd35b2f 100644 --- a/ci-scripts/xml_files/container_sa_n310_2X2_100MHz_quectel.xml +++ b/ci-scripts/xml_files/container_sa_n310_2X2_100MHz_quectel.xml @@ -24,65 +24,35 @@ TEST-SA-FR1-N310-2x2-100MHz 100 MHz TDD SA 2x2 tasks - - 100000 - 111111 - 010010 - 800813 - 040101 - 010001 - 051001 - 071100 - 071101 - 071002 - 010010 - 000001 - 040201 - 200000 - 033333 - - - - Pull_Cluster_Image - Pull Images from Cluster - oai-gnb - matix - - - + Custom_Command Disable Sleep States matix sudo cpupower idle-set -D 0 - - Custom_Command - true - Enable Sleep States + + Pull_Cluster_Image + Pull Images from Cluster + oai-gnb matix - sudo cpupower idle-set -E - - Attach_UE - Attach UE - up2 - - - + Detach_UE true Detach UE up2 - + + Create_Workspace Create new Workspace matix - + + Deploy_Object Deploy gNB (TDD/Band77/100MHz/N310) in a container matix @@ -90,19 +60,13 @@ 3 - - IdleSleep - Sleep - 5 + + Attach_UE + Attach UE + up2 - - IdleSleep - Sleep - 10 - - - + Ping Ping: 100pings in 20sec up2 @@ -112,7 +76,7 @@ 15 - + Iperf iperf (DL/650Mbps/UDP)(30 sec)(single-ue profile) -u -b 650M -t 30 -R -O 10 -l 9000 @@ -122,7 +86,7 @@ 70 - + Iperf iperf (UL/130Mbps/UDP)(30 sec)(single-ue profile) -u -b 130M -t 30 -O 10 @@ -132,7 +96,7 @@ 70 - + Iperf iperf (BIDIR TCP)(30 sec)(single-ue profile) -t 30 --bidir @@ -140,7 +104,20 @@ up2 - + + Detach_UE + true + Detach UE + up2 + + + + IdleSleep + Sleep + 5 + + + Undeploy_Object true Undeploy gNB @@ -150,7 +127,15 @@ 10,100,100,100 - + + Custom_Command + true + Enable Sleep States + matix + sudo cpupower idle-set -E + + + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -159,4 +144,3 @@ - diff --git a/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml b/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml index a809fafa2c..5d1b3dcd95 100644 --- a/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml +++ b/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml @@ -24,85 +24,49 @@ TEST-SA-FR1-N310-2x2-60MHz 60 MHz 2x2 TDD SA DSUUU tasks - - 100000 - 111111 - 010010 - 800813 - 030101 - 010001 - 050001 - 071000 - 071001 - 070002 - 010010 - 000001 - 030201 - 200000 - 333333 - - - - Pull_Cluster_Image - Pull Images from Cluster - oai-gnb - matix - - - + Custom_Command Disable Sleep States matix sudo cpupower idle-set -D 0 - - Custom_Command - true - Enable Sleep States + + Pull_Cluster_Image + Pull Images from Cluster + oai-gnb matix - sudo cpupower idle-set -E - - Attach_UE - Attach UE - up2 - - - + Detach_UE true Detach UE up2 - - Create_Workspace - Create new Workspace - matix - - - Deploy_Object - Deploy gNB (TDD/Band77/60MHz/N310) in a container - matix - ci-scripts/yaml_files/5g_sa_n310_2x2_60MHz - 3 + + + Create_Workspace + Create new Workspace + matix - - IdleSleep - Sleep - 5 + + Deploy_Object + Deploy gNB (TDD/Band77/60MHz/N310) in a container + matix + ci-scripts/yaml_files/5g_sa_n310_2x2_60MHz + 3 - - IdleSleep - Sleep - 10 + + Attach_UE + Attach UE + up2 - + Ping Ping: 100pings in 20sec up2 @@ -112,7 +76,7 @@ 15 - + Iperf iperf (DL/150Mbps/UDP)(30 sec)(single-ue profile) -u -b 150M -t 30 -R @@ -122,7 +86,7 @@ 80 - + Iperf iperf (UL/250Mbps/UDP)(30 sec)(single-ue profile) -u -b 250M -t 30 @@ -132,7 +96,7 @@ 70 - + Iperf iperf (BIDIR TCP)(30 sec)(single-ue profile) -t 30 --bidir @@ -140,7 +104,20 @@ up2 - + + Detach_UE + true + Detach UE + up2 + + + + IdleSleep + Sleep + 5 + + + Undeploy_Object true Undeploy gNB @@ -150,7 +127,15 @@ 20,100,100,100 - + + Custom_Command + true + Enable Sleep States + matix + sudo cpupower idle-set -E + + + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -159,4 +144,3 @@ - diff --git a/ci-scripts/xml_files/container_sa_n310_4X4_60MHz_quectel.xml b/ci-scripts/xml_files/container_sa_n310_4X4_60MHz_quectel.xml index d4d0d51258..45d105de9e 100644 --- a/ci-scripts/xml_files/container_sa_n310_4X4_60MHz_quectel.xml +++ b/ci-scripts/xml_files/container_sa_n310_4X4_60MHz_quectel.xml @@ -24,85 +24,49 @@ TEST-SA-FR1-N310-4x4-60MHz nFAPI 60 MHz 4x4 TDD SA tasks - - 100000 - 111111 - 010010 - 800813 - 030101 - 010001 - 050001 - 071000 - 071001 - 070002 - 010010 - 000001 - 030201 - 200000 - 333333 - - - - Pull_Cluster_Image - Pull Images from Cluster - oai-gnb - matix - - - + Custom_Command Disable Sleep States matix sudo cpupower idle-set -D 0 - - Custom_Command - true - Enable Sleep States + + Pull_Cluster_Image + Pull Images from Cluster + oai-gnb matix - sudo cpupower idle-set -E - - Attach_UE - Attach UE - up2 - - - + Detach_UE true Detach UE up2 - - Create_Workspace - Create new Workspace - matix - - - Deploy_Object - Deploy VNF-PNF (TDD/Band77/60MHz/N310) in a container - matix - ci-scripts/yaml_files/5g_sa_n310_4x4_60MHz - 3 + + + Create_Workspace + Create new Workspace + matix - - IdleSleep - Sleep - 5 + + Deploy_Object + Deploy VNF-PNF (TDD/Band77/60MHz/N310) in a container + matix + ci-scripts/yaml_files/5g_sa_n310_4x4_60MHz + 3 - - IdleSleep - Sleep - 10 + + Attach_UE + Attach UE + up2 - + Ping Ping: 100pings in 20sec up2 @@ -112,7 +76,7 @@ 15 - + Iperf iperf (DL/450Mbps/UDP)(30 sec)(single-ue profile) -u -b 450M -t 30 -R @@ -122,7 +86,7 @@ 80 - + Iperf iperf (UL/120Mbps/UDP)(30 sec)(single-ue profile) -u -b 120M -t 30 @@ -132,7 +96,7 @@ 70 - + Iperf iperf (BIDIR TCP)(30 sec)(single-ue profile) -t 30 --bidir @@ -140,7 +104,20 @@ up2 - + + Detach_UE + true + Detach UE + up2 + + + + IdleSleep + Sleep + 5 + + + Undeploy_Object true Undeploy VNF-PNF @@ -150,7 +127,15 @@ 10,100,100,100 - + + Custom_Command + true + Enable Sleep States + matix + sudo cpupower idle-set -E + + + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -159,4 +144,3 @@ - diff --git a/ci-scripts/xml_files/container_sa_n310_nrue.xml b/ci-scripts/xml_files/container_sa_n310_nrue.xml index 63088afc1c..64311b06cd 100644 --- a/ci-scripts/xml_files/container_sa_n310_nrue.xml +++ b/ci-scripts/xml_files/container_sa_n310_nrue.xml @@ -24,110 +24,62 @@ TEST-5G-NRUE 40 MHz TDD SA tasks - - 060000 - 010000 010001 - 800813 - 020000 - 800814 - 020001 - 000001 - 001000 - 002000 - 000100 - 000200 - 040001 040000 - 333333 - 444444 - 060001 - - - + DeployCoreNetwork Initialize 5G Core oc-cn5g - + Pull_Cluster_Image Pull Images from Cluster oai-gnb avra - + Pull_Cluster_Image Pull Images from Cluster oai-nr-ue caracal - - Custom_Command - Reboot USRP N310 - avra - ssh root@192.168.80.52 reboot ; sleep 45 - - - - Custom_Command - Reboot USRP N310 - caracal - ssh root@192.168.20.2 reboot ; sleep 45 - - + Create_Workspace Create new Workspace avra - + + Deploy_Object Deploy gNB (TDD/Band78/40MHz/N310) in a container avra ci-scripts/yaml_files/5g_sa_n310_gnb 3 - + + Create_Workspace Create new Workspace caracal - + + Deploy_Object Deploy nrUE (TDD/Band78/40MHz/N310) in a container ci-scripts/yaml_files/5g_sa_n310_nrue caracal 3 - - + + Attach_UE Attach OAIUE oai_ue_caracal - - Iperf - iperf (DL/60Mbps/UDP)(30 sec) - -u -b 60M -t 30 -i 1 -R - oai_ue_caracal - oc-cn5g - 25 - 80 - - - - Iperf - iperf (UL/20Mbps/UDP)(30 sec) - -u -b 20M -t 30 -i 1 - oai_ue_caracal - oc-cn5g - 25 - 80 - - - + Ping Ping: 20pings in 20sec oai_ue_caracal @@ -137,7 +89,7 @@ 25 - + Ping Ping: 100pings in 20sec oai_ue_caracal @@ -147,7 +99,35 @@ 30 - + + Iperf + iperf (DL/60Mbps/UDP)(30 sec) + -u -b 60M -t 30 -i 1 -R + oai_ue_caracal + oc-cn5g + 25 + 80 + + + + Iperf + iperf (UL/20Mbps/UDP)(30 sec) + -u -b 20M -t 30 -i 1 + oai_ue_caracal + oc-cn5g + 25 + 80 + + + + Undeploy_Object + true + Undeploy nr UE + caracal + ci-scripts/yaml_files/5g_sa_n310_nrue + + + Undeploy_Object true Undeploy gNB @@ -156,16 +136,8 @@ 20,100,100,100 20,100,100,100 - - - Undeploy_Object - true - Undeploy nr UE - caracal - ci-scripts/yaml_files/5g_sa_n310_nrue - - + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -173,7 +145,7 @@ oai-gnb - + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -181,7 +153,7 @@ oai-nr-ue - + UndeployCoreNetwork Terminate 5G Core true diff --git a/ci-scripts/xml_files/container_sa_n310_nrue_longrun.xml b/ci-scripts/xml_files/container_sa_n310_nrue_longrun.xml index f0d8f4f3b6..6241a9d78d 100644 --- a/ci-scripts/xml_files/container_sa_n310_nrue_longrun.xml +++ b/ci-scripts/xml_files/container_sa_n310_nrue_longrun.xml @@ -24,60 +24,34 @@ LONGRUN-5G-NRUE Longrun 40 MHz TDD SA tasks - - 060000 - 010000 010001 - 800813 - 020000 - 800814 - 020001 - 000001 - 001000 - 000100 - 001000 - 000100 - 001000 - 000100 - 001000 - 000200 - 001000 - 000200 - 001000 - 000200 - 040001 040000 - 333333 - 444444 - 060001 - - - + DeployCoreNetwork Initialize 5G Core oc-cn5g - + Pull_Cluster_Image Pull Images from Cluster oai-gnb avra - + Pull_Cluster_Image Pull Images from Cluster oai-nr-ue caracal - + Create_Workspace Create new Workspace avra - + Deploy_Object Deploy gNB (TDD/Band78/40MHz/N310) in a container avra @@ -85,13 +59,13 @@ 3 - + Create_Workspace Create new Workspace caracal - + Deploy_Object Deploy nrUE (TDD/Band78/40MHz/N310) in a container ci-scripts/yaml_files/5g_sa_n310_nrue @@ -99,33 +73,13 @@ 3 - + Attach_UE Attach OAIUE oai_ue_caracal - - Iperf - iperf (DL/10Mbps/UDP)(10 min) - -u -b 10M -t 600 -i 1 -R - oai_ue_caracal - oc-cn5g - 25 - 80 - - - - Iperf - iperf (UL/2Mbps/UDP)(10 min) - -u -b 2M -t 600 -i 1 - oai_ue_caracal - oc-cn5g - 25 - 80 - - - + Ping Ping: 20pings in 20sec oai_ue_caracal @@ -135,7 +89,125 @@ 25 - + + Iperf + iperf (DL/10Mbps/UDP)(10 min) + -u -b 10M -t 600 -i 1 -R + oai_ue_caracal + oc-cn5g + 25 + 80 + + + + Ping + Ping: 20pings in 20sec + oai_ue_caracal + oc-cn5g + -c 20 + 1 + 25 + + + + Iperf + iperf (DL/10Mbps/UDP)(10 min) + -u -b 10M -t 600 -i 1 -R + oai_ue_caracal + oc-cn5g + 25 + 80 + + + + Ping + Ping: 20pings in 20sec + oai_ue_caracal + oc-cn5g + -c 20 + 1 + 25 + + + + Iperf + iperf (DL/10Mbps/UDP)(10 min) + -u -b 10M -t 600 -i 1 -R + oai_ue_caracal + oc-cn5g + 25 + 80 + + + + Ping + Ping: 20pings in 20sec + oai_ue_caracal + oc-cn5g + -c 20 + 1 + 25 + + + + Iperf + iperf (UL/2Mbps/UDP)(10 min) + -u -b 2M -t 600 -i 1 + oai_ue_caracal + oc-cn5g + 25 + 80 + + + + Ping + Ping: 20pings in 20sec + oai_ue_caracal + oc-cn5g + -c 20 + 1 + 25 + + + + Iperf + iperf (UL/2Mbps/UDP)(10 min) + -u -b 2M -t 600 -i 1 + oai_ue_caracal + oc-cn5g + 25 + 80 + + + + Ping + Ping: 20pings in 20sec + oai_ue_caracal + oc-cn5g + -c 20 + 1 + 25 + + + + Iperf + iperf (UL/2Mbps/UDP)(10 min) + -u -b 2M -t 600 -i 1 + oai_ue_caracal + oc-cn5g + 25 + 80 + + + + Undeploy_Object + true + Undeploy nr UE + caracal + ci-scripts/yaml_files/5g_sa_n310_nrue + + + Undeploy_Object true Undeploy gNB @@ -145,15 +217,7 @@ 20,100,100,100 - - Undeploy_Object - true - Undeploy nr UE - caracal - ci-scripts/yaml_files/5g_sa_n310_nrue - - - + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -161,7 +225,7 @@ oai-gnb - + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -169,7 +233,7 @@ oai-nr-ue - + UndeployCoreNetwork Terminate 5G Core true diff --git a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml index d687120eb9..82cb032372 100644 --- a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml @@ -24,104 +24,47 @@ TEST-SA-FR1-SC-PATTERN2-FDMA-B200 40 MHz TDD (pattern2) SA with SC-FDMA tasks - - 300000 - 311111 - 210000 - 800813 - 230101 - 210001 - 250000 - 250001 - 270000 - 270001 - 270002 - 270003 - 270004 - 260001 - 200002 - 260002 - 250000 - 210010 - 210002 - 230201 - 400000 - 222222 - - - + + Custom_Command + Disable Sleep States + ofqot + sudo cpupower idle-set -D 0 + + + Pull_Local_Registry Pull Images from Local Registry ofqot oai-gnb - - Custom_Command - Disable Sleep States - ofqot - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - ofqot - sudo cpupower idle-set -E - - - + Initialize_UE Initialize Quectel idefix - - Terminate_UE - true - Terminate Quectel - idefix - - - Attach_UE - Attach UE - idefix - - - Detach_UE - true - Detach UE - idefix - - + + Create_Workspace Create new Workspace ofqot - + + Deploy_Object Deploy gNB (TDD/pattern2/Band78/40MHz/B200) with SC-FDMA in a container ofqot ci-scripts/yaml_files/sa_sc_b200_gnb - - IdleSleep - Sleep - 5 - - - - Ping - Ping: 20pings + + Attach_UE + Attach UE idefix - sabox-nepes - -c 20 -i0.5 -w25 - 80 - - + Ping Ping: 20pings in 20sec idefix @@ -131,7 +74,7 @@ 15 - + Ping Ping: 100pings in 20sec idefix @@ -141,7 +84,7 @@ 15 - + Iperf iperf (DL/80Mbps/UDP)(30 sec)(single-ue profile) -u -b 80M -t 30 -R @@ -151,7 +94,7 @@ 95 - + Iperf iperf (UL/18Mbps/UDP)(30 sec) -u -b 18M -t 30 @@ -161,7 +104,7 @@ 95 - + Iperf iperf (BIDIR TCP)(10 sec)(single-ue profile) -t 10 --bidir @@ -169,7 +112,7 @@ sabox-nepes - + Iperf iperf (DL/TCP)(30 sec)(single-ue profile) -t 30 -R @@ -178,7 +121,7 @@ 35 - + Iperf iperf (UL/TCP)(30 sec)(single-ue profile) -t 30 @@ -187,20 +130,54 @@ 5 - + Custom_Command Trigger Reestablishment ofqot echo ci force_reestab | nc -N 127.0.0.1 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' - + + + Ping + Ping: 20pings + idefix + sabox-nepes + -c 20 -i0.5 -w25 + 80 + + + Custom_Command Verify Reestablishment ofqot echo ci get_reestab_count | nc -N 127.0.0.1 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' - + + Ping + Ping: 20pings in 20sec + idefix + sabox-nepes + -c 20 + 1 + 15 + + + + Detach_UE + true + Detach UE + idefix + + + + Terminate_UE + true + Terminate Quectel + idefix + + + Undeploy_Object true Undeploy gNB @@ -210,7 +187,15 @@ 10,100,100,100 - + + Custom_Command + true + Enable Sleep States + ofqot + sudo cpupower idle-set -E + + + Clean_Test_Server_Images true Clean Test Images on Test Server @@ -219,4 +204,3 @@ - diff --git a/ci-scripts/xml_files/cppcheck.xml b/ci-scripts/xml_files/cppcheck.xml index daab4e01c2..7464f16a20 100644 --- a/ci-scripts/xml_files/cppcheck.xml +++ b/ci-scripts/xml_files/cppcheck.xml @@ -21,23 +21,20 @@ --> - build-tab - CPPCHECK Analysis - wrench - - 000002 - 000001 - - - - Create_Workspace - Create new Workspace - carabe - - - Cppcheck_Analysis - Static Code Analysis with cppcheck - carabe - + build-tab + CPPCHECK Analysis + wrench + + + Create_Workspace + Create new Workspace + carabe + + + + Cppcheck_Analysis + Static Code Analysis with cppcheck + carabe + diff --git a/ci-scripts/xml_files/formatting_check.xml b/ci-scripts/xml_files/formatting_check.xml index e54ee1973e..a2b6ddd39c 100644 --- a/ci-scripts/xml_files/formatting_check.xml +++ b/ci-scripts/xml_files/formatting_check.xml @@ -21,18 +21,14 @@ --> - formatting-tab - License and Formatting Checks - wrench - - 000002 - - + formatting-tab + License and Formatting Checks + wrench - - LicenceAndFormattingCheck - License and Formatting Checks - obelix - + + LicenceAndFormattingCheck + License and Formatting Checks + obelix + diff --git a/ci-scripts/xml_files/fr1_5gc_closure.xml b/ci-scripts/xml_files/fr1_5gc_closure.xml index fa524a60aa..3f31d5df55 100644 --- a/ci-scripts/xml_files/fr1_5gc_closure.xml +++ b/ci-scripts/xml_files/fr1_5gc_closure.xml @@ -21,18 +21,14 @@ --> - 5gc-closure - 5GC-Closure - log-out - -060000 - - + 5gc-closure + 5GC-Closure + log-out - - UndeployCoreNetwork - Terminate 5GC - sabox-nepes - + + UndeployCoreNetwork + Terminate 5GC + sabox-nepes + diff --git a/ci-scripts/xml_files/fr1_5gc_start.xml b/ci-scripts/xml_files/fr1_5gc_start.xml index 14bb55f612..8db61264df 100644 --- a/ci-scripts/xml_files/fr1_5gc_start.xml +++ b/ci-scripts/xml_files/fr1_5gc_start.xml @@ -21,19 +21,14 @@ --> - 5gc-start-tab - 5GC-Start - log-in - - 000100 - - - + 5gc-start-tab + 5GC-Start + log-in - - DeployCoreNetwork - Initialize 5GC - sabox-nepes - + + DeployCoreNetwork + Initialize 5GC + sabox-nepes + diff --git a/ci-scripts/xml_files/fr1_cn5g_basic_deploy.xml b/ci-scripts/xml_files/fr1_cn5g_basic_deploy.xml index 3561d11fc9..7baf9b6c54 100644 --- a/ci-scripts/xml_files/fr1_cn5g_basic_deploy.xml +++ b/ci-scripts/xml_files/fr1_cn5g_basic_deploy.xml @@ -21,18 +21,14 @@ --> - cn5g-start-tab - CN5G-Start - log-in - - 000100 - - - + cn5g-start-tab + CN5G-Start + log-in + + + DeployCoreNetwork + Initialize 5G Core + matix-cn5g + - - DeployCoreNetwork - Initialize 5G Core - matix-cn5g - diff --git a/ci-scripts/xml_files/fr1_cn5g_basic_undeploy.xml b/ci-scripts/xml_files/fr1_cn5g_basic_undeploy.xml index 56d7cf74c0..71d872f61a 100644 --- a/ci-scripts/xml_files/fr1_cn5g_basic_undeploy.xml +++ b/ci-scripts/xml_files/fr1_cn5g_basic_undeploy.xml @@ -21,19 +21,14 @@ --> - cn5g-stop-tab - CN5G-Stop - log-in - - 000300 - - - + cn5g-stop-tab + CN5G-Stop + log-in + + + UndeployCoreNetwork + Terminate 5G Core + matix-cn5g + - - UndeployCoreNetwork - Terminate 5G Core - matix-cn5g - - diff --git a/ci-scripts/xml_files/fr1_epc_closure.xml b/ci-scripts/xml_files/fr1_epc_closure.xml index 8f0349073c..72354cc12b 100644 --- a/ci-scripts/xml_files/fr1_epc_closure.xml +++ b/ci-scripts/xml_files/fr1_epc_closure.xml @@ -21,18 +21,14 @@ --> - epc-closure - EPC-Closure - log-out - -060000 - - + epc-closure + EPC-Closure + log-out - - UndeployCoreNetwork - Terminate EPC - ltebox-nano - + + UndeployCoreNetwork + Terminate EPC + ltebox-nano + diff --git a/ci-scripts/xml_files/fr1_epc_start.xml b/ci-scripts/xml_files/fr1_epc_start.xml index 0efaca6d57..246a3ed5d3 100644 --- a/ci-scripts/xml_files/fr1_epc_start.xml +++ b/ci-scripts/xml_files/fr1_epc_start.xml @@ -21,19 +21,14 @@ --> - epc-start-tab - EPC-Start - log-in - - 000100 - - - + epc-start-tab + EPC-Start + log-in - - DeployCoreNetwork - Initialize EPC - ltebox-nano - + + DeployCoreNetwork + Initialize EPC + ltebox-nano + diff --git a/ci-scripts/xml_files/fr1_epc_start_verizon.xml b/ci-scripts/xml_files/fr1_epc_start_verizon.xml index 19f5c03985..df46ba492e 100644 --- a/ci-scripts/xml_files/fr1_epc_start_verizon.xml +++ b/ci-scripts/xml_files/fr1_epc_start_verizon.xml @@ -21,29 +21,24 @@ --> - epc-start-tab - EPC-Start - log-in - - 000100 000101 000102 - - - + epc-start-tab + EPC-Start + log-in - - Initialize_HSS - Initialize HSS - + + Initialize_HSS + Initialize HSS + - - Initialize_MME - Initialize MME - - + + Initialize_MME + Initialize MME + + - - Initialize_SPGW - Initialize SPGW - + + Initialize_SPGW + Initialize SPGW + diff --git a/ci-scripts/xml_files/fr1_oai_cn_deploy.xml b/ci-scripts/xml_files/fr1_oai_cn_deploy.xml index 9cfec6ef58..845cf89086 100644 --- a/ci-scripts/xml_files/fr1_oai_cn_deploy.xml +++ b/ci-scripts/xml_files/fr1_oai_cn_deploy.xml @@ -21,19 +21,14 @@ --> - epc-deploy-tab - EPC-Deploy - log-in - - 000100 - - - + epc-deploy-tab + EPC-Deploy + log-in - - DeployCoreNetwork - Deploy EPC - porcepix-cn4g - + + DeployCoreNetwork + Deploy EPC + porcepix-cn4g + diff --git a/ci-scripts/xml_files/fr1_oai_cn_undeploy.xml b/ci-scripts/xml_files/fr1_oai_cn_undeploy.xml index 1be07ec180..656ef88c0d 100644 --- a/ci-scripts/xml_files/fr1_oai_cn_undeploy.xml +++ b/ci-scripts/xml_files/fr1_oai_cn_undeploy.xml @@ -21,19 +21,14 @@ --> - epc-undeploy-tab - EPC-Undeploy - log-out - - 000200 - - - + epc-undeploy-tab + EPC-Undeploy + log-out - - UndeployCoreNetwork - Undeploy EPC - porcepix-cn4g - + + UndeployCoreNetwork + Undeploy EPC + porcepix-cn4g + diff --git a/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml b/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml index 3d2efb5084..30f307612c 100644 --- a/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml @@ -24,47 +24,44 @@ gNB-PHY-Test-100-2x2-RFemu Timing phytest 100 MHz 2x2 RFemulator tasks - -100000 390101 000001 390109 200000 - - - - Custom_Command - Disable Sleep States - caracal - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - caracal - sudo cpupower idle-set -E + + + Custom_Command + Disable Sleep States + caracal + sudo cpupower idle-set -D 0 - + Initialize_eNB Initialize gNB USRP - caracal + caracal -O ci-scripts/conf_files/gnb.band79.273prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 273 -t 23 -D 127 -m 23 -M 273 -l 2 --device.name rf_emulator --rf_emulator.noise_level_dBFS -36 --log_config.global_log_options level,nocolor,time datalog_rt_stats.100.2x2.yaml NR - numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 + numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 - + IdleSleep Sleep 60 - - + Terminate_eNB - caracal + caracal true Terminate gNB NR + + Custom_Command + true + Enable Sleep States + caracal + sudo cpupower idle-set -E + + diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml index 5adeb17966..f6af5ee485 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml @@ -21,51 +21,48 @@ --> - gNB-PHY-Test-40 - Timing phytest 40 MHz - tasks - -100000 090101 000001 090109 200000 - - - - Custom_Command - Disable Sleep States - caracal - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - caracal - sudo cpupower idle-set -E - + gNB-PHY-Test-40 + Timing phytest 40 MHz + tasks - - Initialize_eNB - Initialize gNB USRP - caracal - -O ci-scripts/conf_files/gnb.band79.106prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 106 -t 23 -D 127 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time + + Custom_Command + Disable Sleep States + caracal + sudo cpupower idle-set -D 0 + + + + Initialize_eNB + Initialize gNB USRP + caracal + -O ci-scripts/conf_files/gnb.band79.106prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 106 -t 23 -D 127 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time datalog_rt_stats.default.yaml - NR - 192.168.20.2 - numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 - + NR + 192.168.20.2 + numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 + - - IdleSleep - Sleep - 60 - + + IdleSleep + Sleep + 60 + - - - Terminate_eNB + + Terminate_eNB true - Terminate gNB - caracal - NR - + Terminate gNB + caracal + NR + + + + Custom_Command + true + Enable Sleep States + caracal + sudo cpupower idle-set -E + diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml index 7821be863c..93053dee90 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml @@ -24,25 +24,15 @@ gNB-PHY-Test-100-2x2 Timing phytest 100 MHz 2x2 tasks - -100000 390101 000001 390109 200000 - - - - Custom_Command - Disable Sleep States - caracal - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - caracal - sudo cpupower idle-set -E + + + Custom_Command + Disable Sleep States + caracal + sudo cpupower idle-set -D 0 - + Initialize_eNB Initialize gNB USRP caracal @@ -50,17 +40,16 @@ datalog_rt_stats.100.2x2.yaml NR 192.168.20.2 - numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 + numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 - + IdleSleep Sleep 60 - - + Terminate_eNB true Terminate gNB @@ -68,4 +57,12 @@ NR + + Custom_Command + true + Enable Sleep States + caracal + sudo cpupower idle-set -E + + diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml index 72e4b5244e..2cd040a47a 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml @@ -24,25 +24,15 @@ gNB-PHY-Test-60 Timing phytest 60 MHz tasks - -100000 190101 000001 190109 200000 - - - - Custom_Command - Disable Sleep States - caracal - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - caracal - sudo cpupower idle-set -E + + + Custom_Command + Disable Sleep States + caracal + sudo cpupower idle-set -D 0 - + Initialize_eNB Initialize gNB USRP caracal @@ -50,17 +40,16 @@ datalog_rt_stats.1x1.60.yaml NR 192.168.20.2 - numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 + numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 - + IdleSleep Sleep 60 - - + Terminate_eNB true Terminate gNB @@ -68,4 +57,12 @@ NR + + Custom_Command + true + Enable Sleep States + caracal + sudo cpupower idle-set -E + + diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml index 1be4a24477..7e5592fb6e 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml @@ -24,25 +24,15 @@ gNB-PHY-Test-60-2x2 Timing phytest 60 MHz 2x2 tasks - -100000 290101 000001 290109 200000 - - - - Custom_Command - Disable Sleep States - caracal - sudo cpupower idle-set -D 0 - - - Custom_Command - true - Enable Sleep States - caracal - sudo cpupower idle-set -E + + + Custom_Command + Disable Sleep States + caracal + sudo cpupower idle-set -D 0 - + Initialize_eNB Initialize gNB USRP caracal @@ -50,17 +40,16 @@ datalog_rt_stats.60.2x2.yaml NR 192.168.20.2 - numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 + numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 - + IdleSleep Sleep 60 - - + Terminate_eNB true Terminate gNB @@ -68,4 +57,12 @@ NR + + Custom_Command + true + Enable Sleep States + caracal + sudo cpupower idle-set -E + + diff --git a/ci-scripts/xml_files/gnb_usrp_build.xml b/ci-scripts/xml_files/gnb_usrp_build.xml index 32043985f5..ea7cc8b8ed 100644 --- a/ci-scripts/xml_files/gnb_usrp_build.xml +++ b/ci-scripts/xml_files/gnb_usrp_build.xml @@ -21,36 +21,30 @@ --> - gnb-build-tab - Build-gNB - wrench - -100000 -000000 -010101 - - + gnb-build-tab + Build-gNB + wrench - - Create_Workspace - Create new Workspace - caracal - + + Custom_Command + Reboot USRP + true + caracal + ssh root@192.168.20.2 reboot + - - TesteNB - Build_eNB - Build gNB (USRP) - caracal - --gNB -w USRP --ninja -c -P --build-lib ldpc_cuda --build-lib ldpc_aal --cmake-opt -DASN1C_EXEC=/opt/asn1c/bin/asn1c --cmake-opt -DPHYSIM_CHECK_FILES="ThresholdsOffload.cmake" - + + Create_Workspace + Create new Workspace + caracal + - - Custom_Command - Reboot USRP - true - caracal - ssh root@192.168.20.2 reboot - + + TesteNB + Build_eNB + Build gNB (USRP) + caracal + --gNB -w USRP --ninja -c -P --build-lib ldpc_cuda --build-lib ldpc_aal --cmake-opt -DASN1C_EXEC=/opt/asn1c/bin/asn1c --cmake-opt -DPHYSIM_CHECK_FILES="ThresholdsOffload.cmake" + diff --git a/ci-scripts/xml_files/lte_oai_cn_deploy.xml b/ci-scripts/xml_files/lte_oai_cn_deploy.xml index 3e4ea86e61..ddfc4dd54d 100644 --- a/ci-scripts/xml_files/lte_oai_cn_deploy.xml +++ b/ci-scripts/xml_files/lte_oai_cn_deploy.xml @@ -21,19 +21,14 @@ --> - epc-deploy-tab - EPC-Deploy - log-in - - 000100 - - - + epc-deploy-tab + EPC-Deploy + log-in - - DeployCoreNetwork - Deploy EPC - nano-cn4g - + + DeployCoreNetwork + Deploy EPC + nano-cn4g + diff --git a/ci-scripts/xml_files/lte_oai_cn_undeploy.xml b/ci-scripts/xml_files/lte_oai_cn_undeploy.xml index b81aa01a1f..df7b4a4038 100644 --- a/ci-scripts/xml_files/lte_oai_cn_undeploy.xml +++ b/ci-scripts/xml_files/lte_oai_cn_undeploy.xml @@ -21,19 +21,14 @@ --> - epc-undeploy-tab - EPC-Undeploy - log-out - - 000200 - - - + epc-undeploy-tab + EPC-Undeploy + log-out - - UndeployCoreNetwork - Undeploy EPC - nano-cn4g - + + UndeployCoreNetwork + Undeploy EPC + nano-cn4g + diff --git a/ci-scripts/xml_files/physim_4g_deploy_run.xml b/ci-scripts/xml_files/physim_4g_deploy_run.xml index cd34037760..3f1f9d10e2 100644 --- a/ci-scripts/xml_files/physim_4g_deploy_run.xml +++ b/ci-scripts/xml_files/physim_4g_deploy_run.xml @@ -21,26 +21,21 @@ --> - build-tab - Physical Simulators Check - wrench - - 800813 - 010201 - - + build-tab + Physical Simulators Check + wrench - - Create_Workspace - Create new Workspace - avra - + + Create_Workspace + Create new Workspace + avra + - - Deploy_Run_OC_PhySim - Deploy and run physical simulator on openshift - physims-4g - avra - + + Deploy_Run_OC_PhySim + Deploy and run physical simulator on openshift + physims-4g + avra + diff --git a/ci-scripts/xml_files/physim_5g_deploy_run.xml b/ci-scripts/xml_files/physim_5g_deploy_run.xml index 1967003124..edc317ea27 100644 --- a/ci-scripts/xml_files/physim_5g_deploy_run.xml +++ b/ci-scripts/xml_files/physim_5g_deploy_run.xml @@ -21,26 +21,21 @@ --> - build-tab - Physical Simulators Check - wrench - - 800813 - 010201 - - + build-tab + Physical Simulators Check + wrench - - Create_Workspace - Create new Workspace - avra - + + Create_Workspace + Create new Workspace + avra + - - Deploy_Run_OC_PhySim - Deploy and run physical simulator on openshift - physims-5g - avra - + + Deploy_Run_OC_PhySim + Deploy and run physical simulator on openshift + physims-5g + avra + diff --git a/ci-scripts/xml_files/physim_gracehopper.xml b/ci-scripts/xml_files/physim_gracehopper.xml index f04ae2541f..533696d28c 100644 --- a/ci-scripts/xml_files/physim_gracehopper.xml +++ b/ci-scripts/xml_files/physim_gracehopper.xml @@ -21,26 +21,21 @@ --> - physim-tab - PhySim - wrench - - 800813 - 010201 - - + physim-tab + PhySim + wrench - - Create_Workspace - Create new Workspace - localhost - + + Create_Workspace + Create new Workspace + localhost + - - Build_Deploy_Docker_PhySim - Build and Deploy PhySim - localhost - -R 5g -E "nr_dlsim|nr_ulsim|ldpctest" -j32 - + + Build_Deploy_Docker_PhySim + Build and Deploy PhySim + localhost + -R 5g -E "nr_dlsim|nr_ulsim|ldpctest" -j32 + diff --git a/ci-scripts/xml_files/physim_timed_gracehopper.xml b/ci-scripts/xml_files/physim_timed_gracehopper.xml index 7658279088..9844f6ebb3 100644 --- a/ci-scripts/xml_files/physim_timed_gracehopper.xml +++ b/ci-scripts/xml_files/physim_timed_gracehopper.xml @@ -21,26 +21,21 @@ --> - physim-timed-tab - PhySim with timing check - wrench - - 800813 - 010202 - - + physim-timed-tab + PhySim with timing check + wrench - - Create_Workspace - Create new Workspace - localhost - + + Create_Workspace + Create new Workspace + localhost + - - Build_Deploy_Docker_PhySim - Build and Deploy PhySim with timing check - localhost - -R 5g -R "nr_dlsim|nr_ulsim|ldpctest" -E physim.5g.nr_dlsim.mcs.mimo.test9 -j1 - + + Build_Deploy_Docker_PhySim + Build and Deploy PhySim with timing check + localhost + -R 5g -R "nr_dlsim|nr_ulsim|ldpctest" -E physim.5g.nr_dlsim.mcs.mimo.test9 -j1 + diff --git a/ci-scripts/xml_files/sa_cn5g_20897_closure.xml b/ci-scripts/xml_files/sa_cn5g_20897_closure.xml index eeab1b32dc..0e8d8db1ba 100644 --- a/ci-scripts/xml_files/sa_cn5g_20897_closure.xml +++ b/ci-scripts/xml_files/sa_cn5g_20897_closure.xml @@ -24,12 +24,8 @@ cn5g-closure CN5G-Closure log-out - - 060000 - - - + UndeployCoreNetwork Terminate 5G Core oc-cn5g-20897 diff --git a/ci-scripts/xml_files/sa_cn5g_20897_start.xml b/ci-scripts/xml_files/sa_cn5g_20897_start.xml index 9c29b83563..e88e84ad88 100644 --- a/ci-scripts/xml_files/sa_cn5g_20897_start.xml +++ b/ci-scripts/xml_files/sa_cn5g_20897_start.xml @@ -24,15 +24,11 @@ cn5g-start-tab CN5G-Start log-in - - 000100 - - - - + DeployCoreNetwork Initialize 5G Core oc-cn5g-20897 + diff --git a/ci-scripts/xml_files/sa_cn5g_closure.xml b/ci-scripts/xml_files/sa_cn5g_closure.xml index beb490dbed..ac02a57431 100644 --- a/ci-scripts/xml_files/sa_cn5g_closure.xml +++ b/ci-scripts/xml_files/sa_cn5g_closure.xml @@ -21,18 +21,14 @@ --> - cn5g-closure - CN5G-Closure - log-out - -060000 - - + cn5g-closure + CN5G-Closure + log-out - - UndeployCoreNetwork - Terminate 5G Core - oc-cn5g - + + UndeployCoreNetwork + Terminate 5G Core + oc-cn5g + diff --git a/ci-scripts/xml_files/sa_cn5g_start.xml b/ci-scripts/xml_files/sa_cn5g_start.xml index a49a2cda18..1a166ef21e 100644 --- a/ci-scripts/xml_files/sa_cn5g_start.xml +++ b/ci-scripts/xml_files/sa_cn5g_start.xml @@ -21,18 +21,14 @@ --> - cn5g-start-tab - CN5G-Start - log-in - -000100 - - - + cn5g-start-tab + CN5G-Start + log-in + + + DeployCoreNetwork + Initialize 5G Core + oc-cn5g + - - DeployCoreNetwork - Initialize 5G Core - oc-cn5g - diff --git a/ci-scripts/xml_files/t2_offload_physim_enc_dec.xml b/ci-scripts/xml_files/t2_offload_physim_enc_dec.xml index 73631a7a3c..afac50ba16 100644 --- a/ci-scripts/xml_files/t2_offload_physim_enc_dec.xml +++ b/ci-scripts/xml_files/t2_offload_physim_enc_dec.xml @@ -20,35 +20,30 @@ --> - test-t2-offload-enc-dec - Test T2 Offload - tasks - - 010204 - 111111 - 402010 - - + test-t2-offload-enc-dec + Test T2 Offload + tasks - - Custom_Command - Disable Sleep States - caracal - sudo cpupower idle-set -D 0 - + + Custom_Command + Disable Sleep States + caracal + sudo cpupower idle-set -D 0 + - - Custom_Command - true - Enable Sleep States - caracal - sudo cpupower idle-set -E - + + Build_Deploy_Source_PhySim + Build and Deploy PhySim T2 Offload tests + caracal + -R 5g-offload -j1 + + + + Custom_Command + true + Enable Sleep States + caracal + sudo cpupower idle-set -E + - - Build_Deploy_Source_PhySim - Build and Deploy PhySim T2 Offload tests - caracal - -R 5g-offload -j1 - diff --git a/ci-scripts/yaml_files/5g_rfsimulator_ntn_leo/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_ntn_leo/docker-compose.yaml index 4e209e09d1..a3f8ec2a7e 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_ntn_leo/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_ntn_leo/docker-compose.yaml @@ -93,7 +93,9 @@ services: - ALL environment: USE_ADDITIONAL_OPTIONS: --rfsim --log_config.global_log_options level,nocolor,time - ASAN_OPTIONS: detect_leaks=0 + --telnetsrv --telnetsrv.listenaddr 192.168.71.140 + --telnetsrv.shrmod ci + ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 depends_on: - oai-ext-dn networks: @@ -123,7 +125,7 @@ services: --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod --rfsimulator.serveraddr 192.168.71.140 --time-sync-I 0.1 --ntn-initial-time-drift -46 - --autonomous-ta --initial-fo 57340 --cont-fo-comp 2 + --initial-fo 57340 --cont-fo-comp 2 --log_config.global_log_options level,nocolor,time --num-ul-actors 1 depends_on: diff --git a/ci-scripts/yaml_files/5g_vrtsim_chanmod/docker-compose.yaml b/ci-scripts/yaml_files/5g_vrtsim_chanmod/docker-compose.yaml new file mode 100644 index 0000000000..503161fc62 --- /dev/null +++ b/ci-scripts/yaml_files/5g_vrtsim_chanmod/docker-compose.yaml @@ -0,0 +1,163 @@ +services: + mysql: + container_name: "rfsim5g-mysql" + image: mysql:8.0 + init: true + volumes: + - ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql + - ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh + environment: + - TZ=Europe/Paris + - MYSQL_DATABASE=oai_db + - MYSQL_USER=test + - MYSQL_PASSWORD=test + - MYSQL_ROOT_PASSWORD=linux + healthcheck: + test: /bin/bash -c "/tmp/mysql-healthcheck.sh" + interval: 10s + timeout: 5s + start_period: 10s + start_interval: 500ms + retries: 30 + networks: + public_net: + ipv4_address: 192.168.71.131 + oai-amf: + container_name: "rfsim5g-oai-amf" + image: oaisoftwarealliance/oai-amf:v2.1.10 + environment: + - TZ=Europe/paris + volumes: + - ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-amf/etc/config.yaml + depends_on: + - mysql + networks: + public_net: + ipv4_address: 192.168.71.132 + oai-smf: + container_name: "rfsim5g-oai-smf" + image: oaisoftwarealliance/oai-smf:v2.1.10 + environment: + - TZ=Europe/Paris + volumes: + - ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-smf/etc/config.yaml + depends_on: + - oai-amf + networks: + public_net: + ipv4_address: 192.168.71.133 + oai-upf: + container_name: "rfsim5g-oai-upf" + image: oaisoftwarealliance/oai-upf:v2.1.10 + init: true + environment: + - TZ=Europe/Paris + volumes: + - ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-upf/etc/config.yaml + depends_on: + - oai-smf + cap_add: + - NET_ADMIN + - SYS_ADMIN + cap_drop: + - ALL + privileged: true + networks: + public_net: + ipv4_address: 192.168.71.134 + interface_name: eth0 + traffic_net: + ipv4_address: 192.168.72.134 + interface_name: eth1 + oai-ext-dn: + privileged: true + container_name: rfsim5g-oai-ext-dn + image: oaisoftwarealliance/trf-gen-cn5g:latest + init: true + entrypoint: /bin/bash -c \ + "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\ + "ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity" + depends_on: + - oai-upf + networks: + traffic_net: + ipv4_address: 192.168.72.135 + healthcheck: + test: /bin/bash -c "ping -c 2 192.168.72.134" + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s + start_interval: 500ms + oai-gnb: + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} + container_name: rfsim5g-oai-gnb + cap_drop: + - ALL + environment: + USE_ADDITIONAL_OPTIONS: -E --log_config.global_log_options level,nocolor,time --device.name vrtsim --vrtsim.role server --vrtsim.chanmod 1 + depends_on: + - oai-ext-dn + networks: + public_net: + ipv4_address: 192.168.71.140 + volumes: + - ../../conf_files/gnb.sa.band78.106prb.vrtsim.2x2.yaml:/opt/oai-gnb/etc/gnb.yaml + - tmp_data:/tmp/ + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + start_period: 10s + start_interval: 500ms + retries: 5 + ipc: host + oai-nr-ue: + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + container_name: rfsim5g-oai-nr-ue + cap_drop: + - ALL + cap_add: + - NET_ADMIN # for interface bringup + - NET_RAW # for ping + environment: + USE_ADDITIONAL_OPTIONS: -E -r 106 --numerology 1 --band 78 -C 3619200000 --ssb 516 --uicc0.imsi 208990100001100 --log_config.global_log_options level,nocolor,time --device.name vrtsim + depends_on: + - oai-gnb + networks: + public_net: + ipv4_address: 192.168.71.150 + devices: + - /dev/net/tun:/dev/net/tun + volumes: + - ../../conf_files/nrue.vrtsim.chanmod.yaml:/opt/oai-nr-ue/etc/nr-ue.yaml + - tmp_data:/tmp/ + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s + start_interval: 500ms + ipc: host + +networks: + public_net: + driver: bridge + name: rfsim5g-oai-public-net + ipam: + config: + - subnet: 192.168.71.128/26 + driver_opts: + com.docker.network.bridge.name: "rfsim5g-public" + traffic_net: + driver: bridge + name: rfsim5g-oai-traffic-net + ipam: + config: + - subnet: 192.168.72.128/26 + driver_opts: + com.docker.network.bridge.name: "rfsim5g-traffic" + +volumes: + tmp_data: diff --git a/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml index f04beeb6c2..4050fa5310 100644 --- a/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml +++ b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml @@ -33,7 +33,7 @@ services: timeout: 5s retries: 5 oai-gnb-aerial: - cpuset: "13-14" + cpuset: "13-16" image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb-aerial}:${TAG:-develop} depends_on: nv-cubb: diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 6f61196e7e..0e4d092916 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -300,7 +300,7 @@ function main() { SIMUS_PHY=1 CMAKE_CMD="$CMAKE_CMD -DENABLE_PHYSIM_TESTS=ON" # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim - TARGET_LIST="$TARGET_LIST dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim" + TARGET_LIST="$TARGET_LIST dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim nr_srssim" echo_info "Will compile dlsim, ulsim, ..." shift;; -V | --vcd) diff --git a/cmake_targets/snap_environment.sh b/cmake_targets/snap_environment.sh deleted file mode 100755 index 1c0725d8b5..0000000000 --- a/cmake_targets/snap_environment.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -export UHD_IMAGES_DIR=$SNAP/uhd_images -exec $@ diff --git a/cmake_targets/tools/Kbuild.cmake b/cmake_targets/tools/Kbuild.cmake deleted file mode 100755 index 7403cd04df..0000000000 --- a/cmake_targets/tools/Kbuild.cmake +++ /dev/null @@ -1,4 +0,0 @@ -src=${dir} -obj-m += ${name}.o -${name}-y += ${objs} -ccflags-y += ${module_cc_opt} diff --git a/cmake_targets/tools/MODULES/CMakeParseArguments.cmake b/cmake_targets/tools/MODULES/CMakeParseArguments.cmake deleted file mode 100755 index ab53b112fa..0000000000 --- a/cmake_targets/tools/MODULES/CMakeParseArguments.cmake +++ /dev/null @@ -1,66 +0,0 @@ -# Analogue for standard CMake module with same name, appeared in CMake 2.8.3. -# -# Used for compatibility with older versions of cmake. - -function(cmake_parse_arguments prefix options one_value_keywords multi_value_keywords) - set(all_keywords ${options} ${one_value_keywords} ${multi_value_keywords}) - # Clear variables before parsing. - foreach(arg ${one_value_keywords} ${multie_value_keywords}) - set(cpa_${arg}) - endforeach() - - foreach(arg ${options}) - set(cpa_${arg} FALSE) - endforeach() - - set(cpa_UNPARSED_ARGUMENTS) - - set(current_keyword) - # Classification for current_keyword: - # 'ONE' or 'MULTY'. - set(current_keyword_type) - - # now iterate over all arguments and fill the result variables - foreach(arg ${ARGN}) - list(FIND all_keywords ${arg} keyword_index) - - if(keyword_index EQUAL -1) - if(current_keyword) - if(current_keyword_type STREQUAL "ONE") - set(cpa_${current_keyword} ${arg}) - set(current_keyword) - else(current_keyword_type STREQUAL "ONE") - list(APPEND cpa_${current_keyword} ${arg}) - endif(current_keyword_type STREQUAL "ONE") - else(current_keyword) - list(APPEND cpa_UNPARSED_ARGUMENTS ${arg}) - endif(current_keyword) - else(keyword_index EQUAL -1) - if(current_keyword AND current_keyword_type STREQUAL "ONE") - message(SEND_ERROR "Value is expected for one-value-keyword ${current_keyword}") - endif(current_keyword AND current_keyword_type STREQUAL "ONE") - list(FIND options ${arg} option_index) - if(option_index EQUAL -1) - set(current_keyword ${arg}) - list(FIND one_value_keywords ${arg} one_value_index) - if(one_value_index EQUAL -1) - set(current_keyword_type "MULTI") - else(one_value_index EQUAL -1) - set(current_keyword_type "ONE") - endif(one_value_index EQUAL -1) - else(option_index EQUAL -1) - set(current_keyword) - set(cpa_${arg} TRUE) - endif(option_index EQUAL -1) - endif(keyword_index EQUAL -1) - endforeach(arg ${ARGN}) - - if(current_keyword AND current_keyword_type STREQUAL "ONE") - message(SEND_ERROR "Value is expected for one-value-keyword ${current_keyword}") - endif(current_keyword AND current_keyword_type STREQUAL "ONE") - - # propagate the result variables to the caller: - foreach(keyword ${all_keywords} UNPARSED_ARGUMENTS) - set(${prefix}_${keyword} ${cpa_${keyword}} PARENT_SCOPE) - endforeach(keyword ${all_keywords}) -endfunction(cmake_parse_arguments prefix options one_value_keywords multi_value_keywords) diff --git a/cmake_targets/tools/MODULES/CMakeUserFindMySQL.cmake b/cmake_targets/tools/MODULES/CMakeUserFindMySQL.cmake deleted file mode 100755 index 1b5de7e3ac..0000000000 --- a/cmake_targets/tools/MODULES/CMakeUserFindMySQL.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# - Find mysqlclient -# Find the native MySQL includes and library -# -# MYSQL_INCLUDE_DIR - where to find mysql.h, etc. -# MYSQL_LIBRARIES - List of libraries when using MySQL. -# MYSQL_FOUND - True if MySQL found. - -IF (MYSQL_INCLUDE_DIR) - # Already in cache, be silent - SET(MYSQL_FIND_QUIETLY TRUE) -ENDIF (MYSQL_INCLUDE_DIR) - -FIND_PATH(MYSQL_INCLUDE_DIR mysql.h - /usr/local/include/mysql - /usr/include/mysql -) - -SET(MYSQL_NAMES mysqlclient mysqlclient_r) -FIND_LIBRARY(MYSQL_LIBRARY - NAMES ${MYSQL_NAMES} - PATHS /usr/lib /usr/local/lib - PATH_SUFFIXES mysql -) - -IF (MYSQL_INCLUDE_DIR AND MYSQL_LIBRARY) - SET(MYSQL_FOUND TRUE) - SET( MYSQL_LIBRARIES ${MYSQL_LIBRARY} ) -ELSE (MYSQL_INCLUDE_DIR AND MYSQL_LIBRARY) - SET(MYSQL_FOUND FALSE) - SET( MYSQL_LIBRARIES ) -ENDIF (MYSQL_INCLUDE_DIR AND MYSQL_LIBRARY) - -IF (MYSQL_FOUND) - IF (NOT MYSQL_FIND_QUIETLY) - MESSAGE(STATUS "Found MySQL: ${MYSQL_LIBRARY}") - ENDIF (NOT MYSQL_FIND_QUIETLY) -ELSE (MYSQL_FOUND) - IF (MYSQL_FIND_REQUIRED) - MESSAGE(STATUS "Looked for MySQL libraries named ${MYSQL_NAMES}.") - MESSAGE(FATAL_ERROR "Could NOT find MySQL library") - ENDIF (MYSQL_FIND_REQUIRED) -ENDIF (MYSQL_FOUND) - -MARK_AS_ADVANCED( - MYSQL_LIBRARY - MYSQL_INCLUDE_DIR - ) - diff --git a/cmake_targets/tools/MODULES/CMakeUserUseBison.cmake b/cmake_targets/tools/MODULES/CMakeUserUseBison.cmake deleted file mode 100755 index 5295a1ba39..0000000000 --- a/cmake_targets/tools/MODULES/CMakeUserUseBison.cmake +++ /dev/null @@ -1,71 +0,0 @@ -# - Look for GNU Bison, the parser generator -# Based off a news post from Andy Cedilnik at Kitware -# Defines the following: -# BISON_EXECUTABLE - path to the bison executable -# BISON_FILE - parse a file with bison -# BISON_PREFIX_OUTPUTS - Set to true to make BISON_FILE produce prefixed -# symbols in the generated output based on filename. -# So for ${filename}.y, you'll get ${filename}parse(), etc. -# instead of yyparse(). -# BISON_GENERATE_DEFINES - Set to true to make BISON_FILE output the matching -# .h file for a .c file. You want this if you're using -# flex. - -IF(NOT DEFINED BISON_PREFIX_OUTPUTS) - SET(BISON_PREFIX_OUTPUTS FALSE) -ENDIF(NOT DEFINED BISON_PREFIX_OUTPUTS) - -IF(NOT DEFINED BISON_GENERATE_DEFINES) - SET(BISON_GENERATE_DEFINES FALSE) -ENDIF(NOT DEFINED BISON_GENERATE_DEFINES) - -IF(NOT BISON_EXECUTABLE) - MESSAGE(STATUS "Looking for bison") - FIND_PROGRAM(BISON_EXECUTABLE bison) - IF(BISON_EXECUTABLE) - MESSAGE(STATUS "Looking for bison -- ${BISON_EXECUTABLE}") - ENDIF(BISON_EXECUTABLE) -ENDIF(NOT BISON_EXECUTABLE) - -IF(BISON_EXECUTABLE) - MACRO(BISON_FILE FILENAME) - GET_FILENAME_COMPONENT(PATH "${FILENAME}" PATH) - IF("${PATH}" STREQUAL "") - SET(PATH_OPT "") - ELSE("${PATH}" STREQUAL "") - SET(PATH_OPT "/${PATH}") - ENDIF("${PATH}" STREQUAL "") - GET_FILENAME_COMPONENT(HEAD "${FILENAME}" NAME_WE) - IF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}") - FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}") - ENDIF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}") - IF(BISON_PREFIX_OUTPUTS) - SET(PREFIX "${HEAD}") - ELSE(BISON_PREFIX_OUTPUTS) - SET(PREFIX "yy") - ENDIF(BISON_PREFIX_OUTPUTS) - SET(OUTFILE "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}/${HEAD}.tab.c") - IF(BISON_GENERATE_DEFINES) - SET(HEADER "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}/${HEAD}.tab.h") - ADD_CUSTOM_COMMAND( - OUTPUT "${OUTFILE}" "${HEADER}" - COMMAND "${BISON_EXECUTABLE}" - ARGS "--name-prefix=${PREFIX}" - "--defines" - "--output-file=${OUTFILE}" - "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}") - SET_SOURCE_FILES_PROPERTIES("${OUTFILE}" "${HEADER}" PROPERTIES GENERATED TRUE) - SET_SOURCE_FILES_PROPERTIES("${HEADER}" PROPERTIES HEADER_FILE_ONLY TRUE) - ELSE(BISON_GENERATE_DEFINES) - ADD_CUSTOM_COMMAND( - OUTPUT "${OUTFILE}" - COMMAND "${BISON_EXECUTABLE}" - ARGS "--name-prefix=${PREFIX}" - "--output-file=${OUTFILE}" - "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}") - SET_SOURCE_FILES_PROPERTIES("${OUTFILE}" PROPERTIES GENERATED TRUE) - ENDIF(BISON_GENERATE_DEFINES) - ENDMACRO(BISON_FILE) -ENDIF(BISON_EXECUTABLE) diff --git a/cmake_targets/tools/MODULES/CMakeUserUseFlex.cmake b/cmake_targets/tools/MODULES/CMakeUserUseFlex.cmake deleted file mode 100755 index 09a3e71e6d..0000000000 --- a/cmake_targets/tools/MODULES/CMakeUserUseFlex.cmake +++ /dev/null @@ -1,46 +0,0 @@ -# - Look for GNU flex, the lexer generator. -# Defines the following: -# FLEX_EXECUTABLE - path to the flex executable -# FLEX_FILE - parse a file with flex -# FLEX_PREFIX_OUTPUTS - Set to true to make FLEX_FILE produce outputs of -# lex.${filename}.c, not lex.yy.c . Passes -P to flex. - -IF(NOT DEFINED FLEX_PREFIX_OUTPUTS) - SET(FLEX_PREFIX_OUTPUTS FALSE) -ENDIF(NOT DEFINED FLEX_PREFIX_OUTPUTS) - -IF(NOT FLEX_EXECUTABLE) - MESSAGE(STATUS "Looking for flex") - FIND_PROGRAM(FLEX_EXECUTABLE flex) - IF(FLEX_EXECUTABLE) - MESSAGE(STATUS "Looking for flex -- ${FLEX_EXECUTABLE}") - ENDIF(FLEX_EXECUTABLE) -ENDIF(NOT FLEX_EXECUTABLE) - -IF(FLEX_EXECUTABLE) - MACRO(FLEX_FILE FILENAME) - GET_FILENAME_COMPONENT(PATH "${FILENAME}" PATH) - IF("${PATH}" STREQUAL "") - SET(PATH_OPT "") - ELSE("${PATH}" STREQUAL "") - SET(PATH_OPT "/${PATH}") - ENDIF("${PATH}" STREQUAL "") - IF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}") - FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}") - ENDIF(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}") - IF(FLEX_PREFIX_OUTPUTS) - GET_FILENAME_COMPONENT(PREFIX "${FILENAME}" NAME_WE) - ELSE(FLEX_PREFIX_OUTPUTS) - SET(PREFIX "yy") - ENDIF(FLEX_PREFIX_OUTPUTS) - SET(OUTFILE "${CMAKE_CURRENT_BINARY_DIR}${PATH_OPT}/lex.${PREFIX}.c") - ADD_CUSTOM_COMMAND( - OUTPUT "${OUTFILE}" - COMMAND "${FLEX_EXECUTABLE}" - ARGS "--prefix=${PREFIX}" - "--outfile=${OUTFILE}" - "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}") - SET_SOURCE_FILES_PROPERTIES("${OUTFILE}" PROPERTIES GENERATED TRUE) - ENDMACRO(FLEX_FILE) -ENDIF(FLEX_EXECUTABLE) diff --git a/cmake_targets/tools/MODULES/FindGCCXML.cmake b/cmake_targets/tools/MODULES/FindGCCXML.cmake deleted file mode 100755 index 6a4daa084d..0000000000 --- a/cmake_targets/tools/MODULES/FindGCCXML.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# FindGCCXML -# ---------- -find_program(GCCXML -NAMES gccxml -PATHS "/usr/bin" -"usr/local/bin" -) -mark_as_advanced(GCCXML) diff --git a/cmake_targets/tools/MODULES/FindKbuild.cmake b/cmake_targets/tools/MODULES/FindKbuild.cmake deleted file mode 100755 index 08accb8551..0000000000 --- a/cmake_targets/tools/MODULES/FindKbuild.cmake +++ /dev/null @@ -1,105 +0,0 @@ -# - Support for building kernel modules - -# This module defines several variables which may be used when build -# kernel modules. -# -# The following variables are set here: -# Kbuild_VERSION_STRING - kernel version. -# Kbuild_ARCH - architecture. -# Kbuild_BUILD_DIR - directory for build kernel and/or its components. -# Kbuild_VERSION_{MAJOR|MINOR|TWEAK} - kernel version components -# Kbuild_VERSION_STRING_CLASSIC - classic representation of version, -# where parts are delimited by dots. -# -# Cache variables which affect on this package: -# CMAKE_SYSTEM_VERSION - change Kbuild_VERSION_STRING -# Also, setting CMAKE_SYSTEM_VERSION will be interpreted by cmake as crosscompile. -# -# Cache variables(ADVANCED) which affect on this package: -# ARCH - if not empty, change Kbuild_ARCH -# KBUILD_DIR - change Kbuild_BUILD_DIR - -set(Kbuild_VERSION_STRING ${CMAKE_SYSTEM_VERSION}) - -# Form classic version view. -string(REGEX MATCH "([0-9]+)\\.([0-9]+)[.-]([0-9]+)" - _kernel_version_match - "${Kbuild_VERSION_STRING}" -) - -if(NOT _kernel_version_match) - message(FATAL_ERROR "Kernel version has unexpected format: ${Kbuild_VERSION_STRING}") -endif(NOT _kernel_version_match) - -set(Kbuild_VERSION_MAJOR ${CMAKE_MATCH_1}) -set(Kbuild_VERSION_MINOR ${CMAKE_MATCH_2}) -set(Kbuild_VERSION_TWEAK ${CMAKE_MATCH_3}) -# Version string for compare -set(Kbuild_VERSION_STRING_CLASSIC "${Kbuild_VERSION_MAJOR}.${Kbuild_VERSION_MINOR}.${Kbuild_VERSION_TWEAK}") - -set(KBUILD_DIR "/lib/modules/${Kbuild_VERSION_STRING}/build" CACHE PATH - "Directory for build linux kernel and/or its components." -) -mark_as_advanced(KBUILD_DIR) - -set(Kbuild_BUILD_DIR "${KBUILD_DIR}") - -set(ARCH "" CACHE STRING - "Architecture for build linux kernel components for, empty string means autodetect." -) -mark_as_advanced(ARCH) - -if(NOT ARCH) - # Autodetect arch. - execute_process(COMMAND uname -m - RESULT_VARIABLE uname_m_result - OUTPUT_VARIABLE ARCH_DEFAULT - ) - if(NOT uname_m_result EQUAL 0) - message("'uname -m' failed:") - message("${ARCH_DEFAULT}") - message(FATAL_ERROR "Failed to determine system architecture.") - endif(NOT uname_m_result EQUAL 0) - - string(REGEX REPLACE "\n$" "" ARCH_DEFAULT "${ARCH_DEFAULT}") - - # Pairs of pattern-replace for postprocess architecture string from - # 'uname -m'. - # Taken from ./Makefile of the kernel build. - set(_kbuild_arch_replacers - "i.86" "x86" - "x86_64" "x86" - "sun4u" "sparc64" - "arm.*" "arm" - "sa110" "arm" - "s390x" "s390" - "parisc64" "parisc" - "ppc.*" "powerpc" - "mips.*" "mips" - "sh[234].*" "sh" - "aarch64.*" "arm64" - ) - - set(_current_pattern) - foreach(p ${_kbuild_arch_replacers}) - if(_current_pattern) - string(REGEX REPLACE "${_current_pattern}" "${p}" ARCH_DEFAULT "${ARCH_DEFAULT}") - set(_current_pattern) - else(_current_pattern) - set(_current_pattern "${p}") - endif(_current_pattern) - endforeach(p ${_kbuild_arch_replacers}) - - set(Kbuild_ARCH "${ARCH_DEFAULT}") -else(NOT ARCH) - # User-provided value is used. - set(Kbuild_ARCH "${ARCH}") -endif(NOT ARCH) - - - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Kbuild - REQUIRED_VARS Kbuild_BUILD_DIR - VERSION_VAR KBuild_VERSION_STRING_CLASSIC -) diff --git a/cmake_targets/tools/MODULES/Kbuild.cmake b/cmake_targets/tools/MODULES/Kbuild.cmake deleted file mode 100755 index 7403cd04df..0000000000 --- a/cmake_targets/tools/MODULES/Kbuild.cmake +++ /dev/null @@ -1,4 +0,0 @@ -src=${dir} -obj-m += ${name}.o -${name}-y += ${objs} -ccflags-y += ${module_cc_opt} diff --git a/cmake_targets/tools/MODULES/cmake_useful.cmake b/cmake_targets/tools/MODULES/cmake_useful.cmake deleted file mode 100755 index af6bbb56c7..0000000000 --- a/cmake_targets/tools/MODULES/cmake_useful.cmake +++ /dev/null @@ -1,229 +0,0 @@ -# Create rule for obtain one file by copying another one -function(rule_copy_file target_file source_file) - add_custom_command(OUTPUT ${target_file} - COMMAND cp -p ${source_file} ${target_file} - DEPENDS ${source_file} - ) -endfunction(rule_copy_file target_file source_file) - -# rule_copy_source([source_dir] file ...) -# -# Create rule for obtain file(s) in binary tree by copiing it from source tree. -# -# Files are given relative to ${source_dir}, if it is set, or -# relative to ${CMAKE_CURRENT_SOURCE_DIR}. -# -# Files will be copied into ${CMAKE_CURRENT_BINARY_DIR} with same -# relative paths. -# -# ${source_dir} should be absolute path(that is, starts from '/'). -# Otherwise first argument is treated as first file to copy. -function(rule_copy_source file) - string(REGEX MATCH "^/" is_abs_path ${file}) - if(is_abs_path) - set(source_dir ${file}) - set(files ${ARGN}) - else(is_abs_path) - set(source_dir ${CMAKE_CURRENT_SOURCE_DIR}) - set(files ${file} ${ARGN}) - endif(is_abs_path) - - foreach(file_real ${files}) - rule_copy_file("${CMAKE_CURRENT_BINARY_DIR}/${file_real}" - ${source_dir}/${file_real}) - endforeach(file_real ${files}) -endfunction(rule_copy_source file) - -# to_abs_path(output_var path [...]) -# -# Convert relative path of file to absolute path: -# use path in source tree, if file already exist there. -# otherwise use path in binary tree. -# If initial path already absolute, return it. -function(to_abs_path output_var) - set(result) - foreach(path ${ARGN}) - string(REGEX MATCH "^/" _is_abs_path ${path}) - if(_is_abs_path) - list(APPEND result ${path}) - else(_is_abs_path) - file(GLOB to_abs_path_file - "${CMAKE_CURRENT_SOURCE_DIR}/${path}" - ) - if(NOT to_abs_path_file) - set (to_abs_path_file "${CMAKE_CURRENT_BINARY_DIR}/${path}") - endif(NOT to_abs_path_file) - list(APPEND result ${to_abs_path_file}) - endif(_is_abs_path) - endforeach(path ${ARGN}) - set("${output_var}" ${result} PARENT_SCOPE) -endfunction(to_abs_path output_var path) - -# is_path_inside_dir(output_var dir path) -# -# Set output_var to true if path is absolute path inside given directory. -# NOTE: Path should be absolute. -macro(is_path_inside_dir output_var dir path) - file(RELATIVE_PATH _rel_path ${dir} ${path}) - string(REGEX MATCH "^\\.\\." _is_not_inside_dir ${_rel_path}) - if(_is_not_inside_dir) - set(${output_var} "FALSE") - else(_is_not_inside_dir) - set(${output_var} "TRUE") - endif(_is_not_inside_dir) -endmacro(is_path_inside_dir output_var dir path) - - -# Write given content to the file. -# -# If file is already exists and its content is same as written one, file -# is not rewritten, so its write timestamp remains unchanged. -function(file_update filename content) - if(EXISTS "${filename}") - file(READ "${filename}" old_content) - if(old_content STREQUAL "${content}") - return() - endif(old_content STREQUAL "${content}") - endif(EXISTS "${filename}") - # File doesn't exists or its content differ. - file(WRITE "${filename}" "${content}") -endfunction(file_update filename content) - - -# Write given content to the file in APPEND mode. -# -# For append we use position variable which should be initialized -# to 0 for every new build process and which is updated every time when -# this function is called. -# If file is already exists and its content at given is same as -# written one, file is not rewritten, so its write timestamp remains unchanged. -# -# Note, that file will not be rewritten if new build process issues less -# APPEND actions than one which create file. -# But similar problem exists for file_update() and even for built-in -# configure_file() command: file will not be removed if new build process -# do not call configure_file() for it. -function(file_update_append filename content POS) - set(pos "${${POS}}") - string(LENGTH "${content}" len) - # Update output variable first. - # This allows to use return() when need not to do anything - math(EXPR pos_new "${pos}+${len}") - set(${POS} "${pos_new}" PARENT_SCOPE) - if(EXISTS "${filename}") - file(READ "${filename}" old_content LIMIT "${len}" OFFSET "${pos}") - if(old_content STREQUAL "${content}") - return() - elseif(old_content STREQUAL "") - file(APPEND "${filename}" "${content}") - return() - endif(old_content STREQUAL "${content}") - else(EXISTS "${filename}") - if(NOT pos EQUAL 0) - message(FATAL_ERROR "Appending to non-zero position to non-existent file.") - endif(NOT pos EQUAL 0) - endif(EXISTS "${filename}") - # File doesn't exists or its content differ. - if(NOT pos EQUAL 0) - file(READ "${filename}" prefix LIMIT "${pos}") - else(NOT pos EQUAL 0) - set(prefix) - endif(NOT pos EQUAL 0) - file(WRITE "${filename}" "${prefix}${content}") -endfunction(file_update_append filename content POS) - - -# Common mechanism for output status message -# when checking different aspects. -# -# Normal using: -# -# check_begin("Checking <...>") -# if(NOT ) -# check_try() # Here message is printed -# # Perform check(try_compile(), etc.) -# endif(NOT ) -# check_end("") # Here message is printed with result. - -# Should be called (unconditionally) when new cheking is issued. -# Note, that given @status_msg is not printed at that step. -function(check_begin status_msg) - set(_check_status_msg ${status_msg} PARENT_SCOPE) - set(_check_has_tries PARENT_SCOPE) -endfunction(check_begin status_msg) - -# Should be called before every real checking, that is which is not come -# from cache variables comparision. -# -# First call of that function is trigger printing of @status_msg, -# passed to check_begin(). -function(check_try) - if(NOT _check_has_tries) - message(STATUS "${_check_status_msg}") - set(_check_has_tries "1" PARENT_SCOPE) - endif(NOT _check_has_tries) -endfunction(check_try) - -# Should be called when cheking is end, and @result_msg should be short -# description of check result. -# If any check_try() has been issued before, -# "@status_msg - @result_msg" -# will be printed. -# Otherwise, -# "@status_msg - [cached] @result_msg" -# will be printed, at it will be the only message for that check. -function(check_end result_msg) - if(NOT _check_has_tries) - message(STATUS "${_check_status_msg} [cached] - ${result_msg}") - else(NOT _check_has_tries) - message(STATUS "${_check_status_msg} - ${result_msg}") - endif(NOT _check_has_tries) - set(_check_status_msg PARENT_SCOPE) - set(_check_has_tries PARENT_SCOPE) -endfunction(check_end result_msg) - -# set_bool_string(var true_string false_string value [CACHE ... | PARENT_SCOPE]) -# -# Set variable to one of two string according to true property of some value. -# -# If 'value' is true-evaluated, 'var' will be set to 'true_string', -# otherwise to 'var' will be set to 'false_string'. -# Like standard set(), macro accept CACHE and PARENT_SCOPE modifiers. -# -# Useful for form meaningful value for cache variables, contained result -# of some operation. -# Also may be used for form message for check_end(). -macro(set_bool_string var true_string false_string value) - # Macro parameters are not a variables, so them cannot be tested - # using 'if(value)'. - # Usage 'if(${value})' leads to warnings since 2.6.4 when ${val} - # is boolean constant - # (because until 2.6.4 'if(value)' always dereference val). - # So copy 'value' to local variable for test it. - set(_set_bool_string_value ${value}) - if(_set_bool_string_value) - set(${var} "${true_string}" ${ARGN}) - else() - set(${var} "${false_string}" ${ARGN}) - endif() -endmacro(set_bool_string) - -# set_zero_string(var true_string false_string value [CACHE ... | PARENT_SCOPE]) -# -# Set variable to one of two string according to zero property of some value. -# -# If 'value' is '0' (presizely), 'var' will be set to 'zero_string', -# otherwise to 'var' will be set to 'nonzero_string'. -# Like standard set(), macro accept CACHE and PARENT_SCOPE modifiers. -# -# Useful for form meaningful value for cache variables, contained result -# of execute_process(). -# Also may be used for form message for check_end(). -macro(set_zero_string var zero_string nonzero_string value) - set(_set_zero_string_value ${value}) - if(_set_zero_string_value EQUAL "0") - set(${var} ${zero_string} ${ARGN}) - else() - set(${var} ${nonzero_string} ${ARGN}) - endif() -endmacro(set_zero_string) \ No newline at end of file diff --git a/cmake_targets/tools/MODULES/kbuild_system.cmake b/cmake_targets/tools/MODULES/kbuild_system.cmake deleted file mode 100755 index 42a1a2d42b..0000000000 --- a/cmake_targets/tools/MODULES/kbuild_system.cmake +++ /dev/null @@ -1,1131 +0,0 @@ -# Provide way for create kernel modules, and perform other actions on them -# in a way similar to standard cmake executables and libraries processing. -# -# NB: At the end of the whole configuration stage -# kbuild_finalize_linking() -# should be executed. -# -# Should be included after: -# find_package(Kbuild) -# -# Cached variables(ADVANCED), which affects on definitions below: -# CROSS_COMPILE - corresponded parameter for 'make' to build kernel objects. -# KBUILD_C_FLAGS - Additional kbuild flags for all builds -# KBUILD_C_FLAGS{DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL} - per-configuration flags. - -include(cmake_useful) - -# Compute path to the auxiliary files. -get_filename_component(kbuild_this_module_dir ${CMAKE_CURRENT_LIST_FILE} PATH) -set(kbuild_aux_dir "${kbuild_this_module_dir}/kbuild_system_files") - -# _declare_per_build_vars( ) -# -# [INTERNAL] Per-build type definitions for given . -# -# Create CACHE STRING variables _{DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL} -# with documentation string where %build% is replaced -# with corresponded build type description. -# -# Default value for variable _ is taken from __INIT. -macro(_declare_per_build_vars variable doc_pattern) - set(_build_type) - foreach(t - RELEASE "release" - DEBUG "debug" - RELWITHDEBINFO "Release With Debug Info" - MINSIZEREL "release minsize" - ) - if(_build_type) - string(REPLACE "%build%" "${t}" _docstring ${doc_pattern}) - set("${variable}_${_build_type}" "${${variable}_${_build_type}_INIT}" - CACHE STRING "${_docstring}") - set(_build_type) - else(_build_type) - set(_build_type "${t}") - endif(_build_type) - endforeach(t) -endmacro(_declare_per_build_vars variable doc_pattern) - - -# Default compiler flags. -# -# These flags are used directly when configuring 'Kbuild', so them should be -# expressed as single-string, where different flags are joinged using ' '. -set(KBUILD_C_FLAGS "" CACHE STRING - "Compiler flags used by Kbuild system during all builds." -) - -# Additional default compiler flags per build type. -set(KBUILD_C_FLAGS_DEBUG_INIT "-g") -set(KBUILD_C_FLAGS_RELWITHDEBINFO_INIT "-g") - -_declare_per_build_vars(KBUILD_C_FLAGS - "Compiler flags used by Kbuild system during %build% builds." -) -mark_as_advanced( - KBUILD_C_FLAGS - KBUILD_C_FLAGS_DEBUG - KBUILD_C_FLAGS_RELEASE - KBUILD_C_FLAGS_RELWITHDEBINFO - KBUILD_C_FLAGS_MINSIZEREL -) - - -# Additional definitions which are passed directly to 'make' for -# kbuild process. -# -# Unlike to compiler flags, these ones are expressed using cmake list. -set(KBUILD_MAKE_FLAGS "" CACHE STRING - "Make flags used by Kbuild system during all builds." -) - -_declare_per_build_vars(KBUILD_MAKE_FLAGS - "Make flags used by Kbuild system during %build% builds." -) - -mark_as_advanced( - KBUILD_MAKE_FLAGS - KBUILD_MAKE_FLAGS_DEBUG - KBUILD_MAKE_FLAGS_RELEASE - KBUILD_MAKE_FLAGS_RELWITHDEBINFO - KBUILD_MAKE_FLAGS_MINSIZEREL -) - -set(CROSS_COMPILE "" CACHE STRING "Cross compilation prefix for build linux kernel objects.") -mark_as_advanced(CROSS_COMPILE) - -# Property prefixed with 'KMODULE_' is readonly for outer use, -# unless explicitely noted in its description. - -# Property is set for every target described kernel module. -# Concrete property's value currently has no special meaning. -define_property(TARGET PROPERTY KMODULE_TYPE - BRIEF_DOCS "Whether given target describes kernel module." - FULL_DOCS "Whether given target describes kernel module." -) - -# Absolute filename of .ko file which is built. -# NOTE: Imported targets use -# KMODULE_IMPORTED_MODULE_LOCATION -# property instead. -define_property(TARGET PROPERTY KMODULE_MODULE_LOCATION - BRIEF_DOCS "Location of the built kernel module." - FULL_DOCS "Location of the built kernel module." -) - -# Name of the given module, like "ext4" or "kedr". -define_property(TARGET PROPERTY KMODULE_MODULE_NAME - BRIEF_DOCS "Name of the kernel module." - FULL_DOCS "Name of the kernel module." -) - - -# Absolute filename of Module.symvers file which is built. -# NOTE: Imported targets use -# KMODULE_IMPORTED_SYMVERS_LOCATION -# property instead. -define_property(TARGET PROPERTY KMODULE_SYMVERS_LOCATION - BRIEF_DOCS "Location of the symvers file of the kernel module." - FULL_DOCS "Location of the symvers file of the kernel module." -) - -# Property is "TRUE" for every target described imported kernel module, -# "FALSE" for other targets described kernel module. -define_property(TARGET PROPERTY KMODULE_IMPORTED - BRIEF_DOCS "Whether given target describes imported kernel module." - FULL_DOCS "Whether given target describes imported kernel module." -) - -# Absolute filename of .ko file which is imported. -# Property may be set after -# kbuild_add_module(... IMPORTED) -# for allow loading of given module or perform other actions required -# kernel module itself. -# -# Analogue for KMODULE_MODULE_LOCATION property of normal(non-exported) -# kernel module target. -define_property(TARGET PROPERTY KMODULE_IMPORTED_MODULE_LOCATION - BRIEF_DOCS "Location of the imported kernel module." - FULL_DOCS "Location of the imported kernel module." -) - -# Absolute filename of Module.symvers file for imported kernel module. -# Property may be set after -# kbuild_add_module(... IMPORTED) -# for allow linking with given module or perform other actions required -# its symbols. -# -# Analogue for KMODULE_MODULE_SYMVERS_LOCATION property of normal(non-exported) -# kernel module target. -define_property(TARGET PROPERTY KMODULE_IMPORTED_SYMVERS_LOCATION - BRIEF_DOCS "Location of the symvers file for imported kernel module." - FULL_DOCS "Location of the symvers file for imported kernel module." -) - -# Helpers for simple extract some kernel module properties. - -# kbuild_get_module_location(RESULT_VAR name) -# -# Return location of the module, determined by the property -# KMODULE_MODULE_LOCATION or KMODULE_IMPORTED_MODULE_LOCATION for -# imported target. In the last case the property is checked for being set. -function(kbuild_get_module_location RESULT_VAR name) - if(NOT TARGET ${name}) - message(FATAL_ERROR "\"${name}\" is not really a target.") - endif(NOT TARGET ${name}) - get_property(kmodule_type TARGET ${name} PROPERTY KMODULE_TYPE) - if(NOT kmodule_type) - message(FATAL_ERROR "\"${name}\" is not really a target for kernel module.") - endif(NOT kmodule_type) - get_property(kmodule_imported TARGET ${name} PROPERTY KMODULE_IMPORTED) - if(kmodule_imported) - get_property(module_location TARGET ${name} PROPERTY KMODULE_IMPORTED_MODULE_LOCATION) - if(NOT module_location) - message(FATAL_ERROR "target \"${name}\" for imported module has no property KMODULE_IMPORTED_MODULE_LOCATION set.") - endif(NOT module_location) - else(kmodule_imported) - get_property(module_location TARGET ${name} PROPERTY KMODULE_MODULE_LOCATION) - endif(kmodule_imported) - set(${RESULT_VAR} ${module_location} PARENT_SCOPE) -endfunction(kbuild_get_module_location RESULT_VAR module) - -# kbuild_get_symvers_location(RESULT_VAR name) -# -# Return location of the symvers file for the module, determined by the -# property KMODULE_SYMVERS_LOCATION or KMODULE_IMPORTED_SYMVERS_LOCATION -# for imported target. In the last case the property is checked for being set. -function(kbuild_get_symvers_location RESULT_VAR name) - if(NOT TARGET ${name}) - message(FATAL_ERROR "\"${name}\" is not really a target.") - endif(NOT TARGET ${name}) - get_property(kmodule_type TARGET ${name} PROPERTY KMODULE_TYPE) - if(NOT kmodule_type) - message(FATAL_ERROR "\"${name}\" is not really a target for kernel module.") - endif(NOT kmodule_type) - get_property(kmodule_imported TARGET ${name} PROPERTY KMODULE_IMPORTED) - if(kmodule_imported) - get_property(symvers_location TARGET ${name} PROPERTY KMODULE_IMPORTED_SYMVERS_LOCATION) - if(NOT symvers_location) - message(FATAL_ERROR "target \"${name}\" for imported module has no property KMODULE_IMPORTED_SYMVERS_LOCATION set.") - endif(NOT symvers_location) - else(kmodule_imported) - get_property(symvers_location TARGET ${name} PROPERTY KMODULE_SYMVERS_LOCATION) - endif(kmodule_imported) - set(${RESULT_VAR} ${symvers_location} PARENT_SCOPE) -endfunction(kbuild_get_symvers_location RESULT_VAR module) - -# kbuild_add_module( [EXCLUDE_FROM_ALL] [MODULE_NAME ] [ ...]) -# -# Build kernel module from , analogue of add_library(). -# -# Source files are divided into two categories: -# -Object sources -# -Other sourses -# -# Object sources are those sources, which may be used in building kernel -# module externally. -# Follow types of object sources are supported now: -# .c: a file with the code in C language; -# .S: a file with the code in assembly language; -# .o_shipped: shipped file in binary format, -# does not require additional preprocessing. -# -# Other sources are treated as only prerequisite of building process. -# -# -# kbuild_add_module( [MODULE_NAME ] IMPORTED) -# -# Create target, corresponded to the imported kernel module. -# In that case KMODULE_IMPORTED_* properties should be set manually if needed. -# -# In either case, if MODULE_NAME option is given, it determine name -# of the kernel module. Otherwise itself is used. -function(kbuild_add_module name) - cmake_parse_arguments(kbuild_add_module "IMPORTED;EXCLUDE_FROM_ALL" "MODULE_NAME" "" ${ARGN}) - if(kbuild_add_module_MODULE_NAME) - set(module_name "${kbuild_add_module_MODULE_NAME}") - else(kbuild_add_module_MODULE_NAME) - set(module_name "${name}") - endif(kbuild_add_module_MODULE_NAME) - - string(LENGTH ${module_name} module_name_len) - if(module_name_len GREATER 55) - # Name of the kernel module should fit into array of size (64-sizeof(unsigned long)). - # On 64-bit systems(most restricted) this is 56. - # Even 56 length is not good, as it is not include null character. - # Without it, old versions of rmmod failed to unload module. - message(SEND_ERROR "Kernel module name exceeds 55 characters: '${module_name}'") - endif(module_name_len GREATER 55) - - if(kbuild_add_module_IMPORTED) - # Creation of IMPORTED target is simple. - add_custom_target(${name}) - set_property(TARGET ${name} PROPERTY KMODULE_TYPE "kmodule") - set_property(TARGET ${name} PROPERTY KMODULE_IMPORTED "TRUE") - set_property(TARGET ${name} PROPERTY KMODULE_MODULE_NAME "${module_name}") - return() - endif(kbuild_add_module_IMPORTED) - - if(kbuild_add_module_EXCLUDE_FROM_ALL) - set(all_arg) - else(kbuild_add_module_EXCLUDE_FROM_ALL) - set(all_arg "ALL") - endif(kbuild_add_module_EXCLUDE_FROM_ALL) - - # List of all source files, which are given. - set(sources ${kbuild_add_module_UNPARSED_ARGUMENTS}) - - # Sources with absolute paths - to_abs_path(sources_abs ${sources}) - # list of files from which module building is depended - set(depend_files) - # Sources of "c" type, but without extension. - # Used for clean files, and for out-of-source builds do not create - # files in source tree. - set(c_sources_noext_abs) - # The sources with the code in assembly - set(asm_sources_noext_abs) - # Sources of "o_shipped" type, but without extension - set(shipped_sources_noext_abs) - # Categorize sources - foreach(source_abs ${sources_abs}) - get_filename_component(ext ${source_abs} EXT) - if(ext STREQUAL ".c" OR ext STREQUAL ".S" OR ext STREQUAL ".o_shipped") - # Real sources - # Move source into binary tree, if needed - copy_source_to_binary_dir("${source_abs}" source_abs) - - get_filename_component(source_noext "${source_abs}" NAME_WE) - get_filename_component(source_dir "${source_abs}" PATH) - set(source_noext_abs "${source_dir}/${source_noext}") - if(ext STREQUAL ".c") - # c-source - list(APPEND c_sources_noext_abs ${source_noext_abs}) - elseif(ext STREQUAL ".S") - # asm source - list(APPEND asm_sources_noext_abs ${source_noext_abs}) - elseif(ext STREQUAL ".o_shipped") - # shipped-source - list(APPEND shipped_sources_noext_abs ${source_noext_abs}) - endif(ext STREQUAL ".c") - endif(ext STREQUAL ".c" OR ext STREQUAL ".S" OR ext STREQUAL ".o_shipped") - # In any case, add file to depend list - list(APPEND depend_files ${source_abs}) - endforeach(source_abs ${sources_abs}) - - # Object sources relative to current binary dir - # (for $(module)-y :=) - set(obj_sources_noext_rel) - foreach(obj_sources_noext_abs - ${c_sources_noext_abs} ${asm_sources_noext_abs} ${shipped_sources_noext_abs}) - file(RELATIVE_PATH obj_source_noext_rel - ${CMAKE_CURRENT_BINARY_DIR} ${obj_sources_noext_abs}) - list(APPEND obj_sources_noext_rel ${obj_source_noext_rel}) - endforeach(obj_sources_noext_abs) - - if(NOT obj_sources_noext_rel) - message(FATAL_ERROR "List of object files for building kernel module ${name} is empty.") - endif(NOT obj_sources_noext_rel) - - set(obj_sources_rel) - # Detect, if build simple - source object name coincide with module name - - if(NOT obj_sources_noext_rel STREQUAL ${name}) - # Check, whether only one of source object names coincide with module name. - # This situation is incorrect for kbuild system. - list(FIND obj_sources_noext_rel ${name} is_objects_contain_name) - if(is_objects_contain_name GREATER -1) - message(FATAL_ERROR "Module should be built " - "either from only one object with same name, " - "or from objects with names different from the name of the module") - endif(is_objects_contain_name GREATER -1) - - foreach(obj_source_noext_rel ${obj_sources_noext_rel}) - list(APPEND obj_sources_rel "${obj_source_noext_rel}.o") - endforeach(obj_source_noext_rel ${obj_sources_noext_rel}) - endif(NOT obj_sources_noext_rel STREQUAL ${name}) - - _get_directory_property_chained(ccflags KBUILD_COMPILE_DEFINITIONS " ") - _get_directory_property_chained(include_dirs KBUILD_INCLUDE_DIRECTORIES) - - # Target for create module. - add_custom_target(${name} ALL - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.ko" - "${CMAKE_CURRENT_BINARY_DIR}/${_kbuild_symvers}" - ) - - # Create .cmd files for 'shipped' sources. - # Gcc does not create them automatically for some reason. - set(cmd_create_command) - if(shipped_sources_noext_abs) - foreach(shipped_source_noext_abs ${shipped_source_noext_abs}) - get_filename_component(shipped_dir ${shipped_source_noext_abs} PATH) - get_filename_component(shipped_name ${shipped_source_noext_abs} NAME) - list(APPEND cmd_create_command - COMMAND printf "cmd_%s.o := cp -p %s.o_shipped %s.o\\n" - "${shipped_source_noext_abs}" - "${shipped_source_noext_abs}" - "${shipped_source_noext_abs}" - > "${shipped_dir}/.${shipped_name}.o.cmd") - endforeach(shipped_source_noext_abs ${shipped_source_noext_abs}) - endif(shipped_sources_noext_abs) - - # User-defined parameters for 'make' - set(make_flags ${KBUILD_MAKE_FLAGS}) - _get_per_build_var(make_flags_per_build KBUILD_MAKE_FLAGS) - list(APPEND make_flags ${make_flags_per_build}) - - # Rule for create module(and symvers file). - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.ko" - "${CMAKE_CURRENT_BINARY_DIR}/${_kbuild_symvers}" - ${cmd_create_command} - COMMAND $(MAKE) ${make_flags} ${kbuild_additional_make_flags} - -C ${Kbuild_BUILD_DIR} M=${CMAKE_CURRENT_BINARY_DIR} modules -# Update timestamps for targets. -# In some cases Kbuild system may decide do not update resulted files -# even in case when depencies newer. -# Updating timestamps prevent command to be executed every make call. - COMMAND touch "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.ko" - "${CMAKE_CURRENT_BINARY_DIR}/${_kbuild_symvers}" - DEPENDS ${depend_files} - "${CMAKE_CURRENT_BINARY_DIR}/Kbuild" - COMMENT "Building kernel module ${name}" - ) - - # Fill properties for the target. - set_property(TARGET ${name} PROPERTY KMODULE_TYPE "kmodule") - set_property(TARGET ${name} PROPERTY KMODULE_IMPORTED "FALSE") - set_property(TARGET ${name} PROPERTY KMODULE_MODULE_NAME "${module_name}") - - set_property(TARGET ${name} PROPERTY KMODULE_MODULE_LOCATION - "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.ko" - ) - set_property(TARGET ${name} PROPERTY KMODULE_SYMVERS_LOCATION - "${CMAKE_CURRENT_BINARY_DIR}/${_kbuild_symvers}" - ) - - # Internal properties - set_property(TARGET ${name} PROPERTY KMODULE_BINARY_DIR - "${CMAKE_CURRENT_BINARY_DIR}" - ) - set_property(TARGET ${name} PROPERTY KMODULE_OBJ_SOURCES ${obj_sources_rel}) - set_property(TARGET ${name} PROPERTY KMODULE_COMPILE_FLAGS ${ccflags}) - set_property(TARGET ${name} PROPERTY KMODULE_INCLUDE_DIRECTORIES ${include_dirs}) - - - # Add target to the list of modules for built. - set_property(GLOBAL APPEND PROPERTY KMODULE_TARGETS "${name}") - - # The rule to clean files - _kbuild_module_clean_files(${name} - C_SOURCE ${c_sources_noext_abs} - ASM_SOURCE ${asm_sources_noext_abs} - SHIPPED_SOURCE ${shipped_sources_noext_abs}) -endfunction(kbuild_add_module name) - -# kbuild_include_directories(dirs ...) -# -# Add include directories for Kbuild process. -macro(kbuild_include_directories) - set_property(DIRECTORY APPEND PROPERTY KBUILD_INCLUDE_DIRECTORIES ${ARGN}) -endmacro(kbuild_include_directories) - -# kbuild_add_definitions (flags) -# -# Specify additional flags for compile kernel module. -# -# Note that multiple flags should be specified as single string, -# delimited with ' '. -function(kbuild_add_definitions flags) - get_property(current_flags DIRECTORY PROPERTY KBUILD_COMPILE_DEFINITIONS) - _string_join(" " current_flags "${current_flags}" "${flags}") - set_property(DIRECTORY PROPERTY KBUILD_COMPILE_DEFINITIONS "${current_flags}") -endfunction(kbuild_add_definitions flags) - -# There is no control for kbuild make flags except default values. -# Support for kbuild_add_make_definitions may be added if needed. - - -# kbuild_link_module( [ ...]) -# -# Link kernel module with other modules, that allows to use symbols from -# other modules. -# -# may be: -# 1) target name for other kernel module intended for build -# 2) target name for imported kernel module with -# KMODULE_IMPORTED_SYMVERS_LOCATION property set -# 3) absolute path to symvers file of other kernel module. -# -# In any case, file-level dependency will be created for symvers file to link with. -# In the first case, also target-level dependency will be added -# -# Analogue for target_link_library(). -# -# May be used only from the same directory, where module target is created. -function(kbuild_link_module name) - # Check that @name corresponds to kernel module target for build. - get_property(is_module TARGET ${name} PROPERTY KMODULE_TYPE SET) - if(NOT is_module) - message(FATAL_ERROR "kbuild_module_link: passed \n\t\"${name}\"\n which is not kernel module target.") - endif(NOT is_module) - get_property(module_imported TARGET ${name} PROPERTY KMODULE_IMPORTED) - if(kmodule_imported) - message(FATAL_ERROR "Imported kernel module target \"${name}\" may not be linked.") - endif(kmodule_imported) - - get_property(module_name TARGET ${name} PROPERTY KMODULE_MODULE_NAME) - - foreach(l ${ARGN}) - string(REGEX MATCH "/" link_is_file ${l}) - if(link_is_file) - string(REGEX MATCH "^/" file_is_absolute ${l}) - if(NOT file_is_absolute) - message(FATAL_ERROR "kbuild_module_link: passed filename\n\t\"${link}\"\nwhich is not absolute as .") - endif(NOT file_is_absolute) - set(symvers_location "${l}") - # Do not require symvers file to be already existed. - else(link_is_file) - if(NOT TARGET ${l}) - message(FATAL_ERROR "kbuild_module_link: passed link\n\t\"${l}\"\n which is neither an absolute path to symvers file nor a target.") - endif(NOT TARGET ${l}) - get_property(kmodule_type TARGET ${l} PROPERTY KMODULE_TYPE) - if(NOT kmodule_type) - message(FATAL_ERROR "kbuild_module_link: passed target\n\t\"${l}\"\n which is not a target for kernel module as link.") - endif(NOT kmodule_type) - get_property(kmodule_imported TARGET ${l} PROPERTY KMODULE_IMPORTED) - if(kmodule_imported) - get_property(symvers_location TARGET ${l} PROPERTY KMODULE_IMPORTED_SYMVERS_LOCATION) - if(NOT symvers_location) - message(FATAL_ERROR "kbuild_module_link: passed imported target\n\t\"${l}\"\n without \"KMODULE_IMPORTED_SYMVERS_LOCATION\" property set as link.") - endif(NOT symvers_location) - else(kmodule_imported) - get_property(symvers_location TARGET ${l} PROPERTY KMODULE_SYMVERS_LOCATION) - # Target dependency is added only for non-imported target. - add_dependencies(${name} ${l}) - endif(kmodule_imported) - endif(link_is_file) - add_custom_command(OUTPUT - "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.ko" - "${CMAKE_CURRENT_BINARY_DIR}/${_kbuild_symvers}" - DEPENDS ${symvers_location} - APPEND - ) - set_property(TARGET ${name} APPEND PROPERTY KMODULE_DEPEND_SYMVERS ${symvers_location}) - endforeach(l ${ARGN}) -endfunction(kbuild_link_module name) - -# kbuild_finalize_linking() -# -# Should be called after all kernel modules and their links defined. -# Usually this is the end of main CMakeLists.txt file. -function(kbuild_finalize_linking) - _get_per_build_var(ccflags_per_build KBUILD_C_FLAGS) - - get_property(kmodule_targets GLOBAL PROPERTY KMODULE_TARGETS) - foreach(m ${kmodule_targets}) - get_property(module_binary_dir TARGET ${m} PROPERTY KMODULE_BINARY_DIR) - get_property(module_name TARGET ${m} PROPERTY KMODULE_MODULE_NAME) - get_property(module_symvers_cmake TARGET ${m} PROPERTY KMODULE_DEPEND_SYMVERS) - - get_property(obj_sources TARGET ${m} PROPERTY KMODULE_OBJ_SOURCES) - get_property(ccflags_local TARGET ${m} PROPERTY KMODULE_COMPILE_FLAGS) - get_property(include_dirs TARGET ${m} PROPERTY KMODULE_INCLUDE_DIRECTORIES) - - # Combine all compiler flags together - _string_join(" " ccflags "${KBUILD_C_FLAGS}" "${ccflags_local}") - foreach(dir ${include_dirs}) - _string_join(" " ccflags "${ccflags}" "-I${dir}") - endforeach(dir ${include_dirs}) - _string_join(" " ccflags "${ccflags}" "${ccflags_per_build}") - - string(REPLACE ";" " " module_symvers "${module_symvers_cmake}") - - if(obj_sources) - set(obj_src_string "${module_name}-y := ") - foreach(obj ${obj_sources}) - set(obj_src_string "${obj_src_string} ${obj}") - endforeach(obj ${obj_sources}) - else(obj_sources) - # Simple building process - module name is same as the name - # of the only source. - set(obj_src_string "") - endif(obj_sources) - # Configure kbuild file - configure_file(${kbuild_this_module_dir}/kbuild_system_files/Kbuild.in - ${module_binary_dir}/Kbuild - ) - endforeach(m ${kmodule_targets}) -endfunction(kbuild_finalize_linking) - -# kbuild_install(TARGETS ... -# [[MODULE|SYMVERS] -# DESTINATION -# [CONFIGURATIONS [...]] -# [COMPONENT ] -# ]+) -# -# Install kernel module(s) and/or symvers file(s) into given directory. -# -# Almost all options means same as for install() cmake command. -# 'MODULE' refers to kernel module itself, SYMVERS refers symvers file. -# -# Unlike to standard install() command, there is no default destination -# directory neither for modules nor for symvers files. -# So, at least one rule should be defined, and 'DESTINATION' option -# should be set for every rule. -# -# TODO: support for 'EXPORT' mode. -function(kbuild_install type) - if(NOT type STREQUAL "TARGETS") - message(FATAL_ERROR "Only 'TARGETS' mode is currently supported") - endif(NOT type STREQUAL "TARGETS") - - parse_install_arguments(kbuild_install - "MODULE;SYMVERS" # Section types - "" "DESTINATION;COMPONENT" "CONFIGURATIONS" # Section keywords classification. - ${ARGN} - ) - - set(kbuild_install_TARGETS ${kbuild_install_GLOBAL_ARGUMENTS}) - if(NOT kbuild_install_TARGETS) - message(FATAL_ERROR "No targets given for kbuild_install() command") - endif(NOT kbuild_install_TARGETS) - - if(NOT kbuild_install_sections) - message(FATAL_ERROR "There is no default destination for install kernel module components, but no section described it is given.") - endif(NOT kbuild_install_sections) - - foreach(section_type ${kbuild_install_sections}) - if(NOT kbuild_install_${section_type}_DESTINATION) - message(FATAL_ERROR "DESTINATION is not defined for section ${section_type}") - endif(NOT kbuild_install_${section_type}_DESTINATION) - # All additional arguments for given section. - set(install_args_${section_type} - DESTINATION "${kbuild_install_${section_type}_DESTINATION}") - if(kbuild_install_${section_type}_CONFIGURATION) - list(APPEND install_args_${section_type} - CONFIGURATION "${kbuild_install_${section_type}_CONFIGURATION}" - ) - endif(kbuild_install_${section_type}_CONFIGURATION) - if(kbuild_install_${section_type}_COMPONENT) - list(APPEND install_args_${section_type} - COMPONENT "${kbuild_install_${section_type}_COMPONENT}" - ) - endif(kbuild_install_${section_type}_COMPONENT) - # Module installation. - if(section_type STREQUAL "MODULE" OR section_type STREQUAL "ALL") - # Combine locations for all modules in one list. - set(module_locations) - foreach(t ${kbuild_install_TARGETS}) - kbuild_get_module_location(module_location ${t}) - list(APPEND module_locations ${module_location}) - endforeach(t ${kbuild_install_TARGETS}) - # .. and install them at once. - install(FILES ${module_locations} ${install_args_${section_type}}) - endif(section_type STREQUAL "MODULE" OR section_type STREQUAL "ALL") - # Symvers installation. - if(section_type STREQUAL "SYMVERS" OR section_type STREQUAL "ALL") - # Because of renaming, symvers files should be installed separately. - foreach(t ${kbuild_install_TARGETS}) - kbuild_get_symvers_location(symvers_location ${t}) - get_property(module_name TARGET ${t} PROPERTY KMODULE_MODULE_NAME) - install(FILES ${symvers_location} - RENAME "${module_name}.symvers" - ${install_args_${section_type}} - ) - endforeach(t ${kbuild_install_TARGETS}) - endif(section_type STREQUAL "SYMVERS" OR section_type STREQUAL "ALL") - endforeach(section_type ${kbuild_install_sections}) -endfunction(kbuild_install type) - - -# kbuild_try_compile(RESULT_VAR bindir srcfile|SOURCES src ... -# [CMAKE_FLAGS ] -# [KBUILD_COMPILE_DEFINITIONS flags ...] -# [OUTPUT_VARIABLE var]) -# -# Similar to try_module in simplified form, but compile srcfile as -# kernel module, instead of user space program. -# -# KBUILD_COMPILE_DEFINITIONS contains compiler definition flags for -# build kernel module. -# -# Possible CMAKE_FLAGS which has special semantic: -# KBUILD_INCLUDE_DIRECTORIES - include directories for build kernel module -# KBUILD_LINK_MODULE - symvers file(s) for link module with other modules. -function(kbuild_try_compile RESULT_VAR bindir srcfile) - cmake_parse_arguments(kbuild_try_compile "" "OUTPUT_VARIABLE" "CMAKE_FLAGS;KBUILD_COMPILE_DEFINITIONS" ${ARGN}) - if(srcfile STREQUAL "SOURCES") - set(srcfiles ${kbuild_try_compile_UNPARSED_ARGUMENTS}) - else(srcfile STREQUAL "SOURCES") - set(srcfiles ${srcfile}) - endif(srcfile STREQUAL "SOURCES") - - # Inside try_compile project values of variables - # CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR - # differs from ones in current project. - # - # So make all paths absolute before pass them into try_compile project. - # Note, that copiing files into binary dir is nevertheless performed - # in the try_compile project, because it bases on real current binary dir. - to_abs_path(srcfiles_abs ${srcfiles}) - - # Collect parameters to try_compile() function - set(cmake_flags - "-DSOURCES:STRING=${srcfiles_abs}" # Source file(s) - "-DCMAKE_MODULE_PATH:PATH=${CMAKE_MODULE_PATH}" # Path for search include files. - ${kbuild_try_compile_CMAKE_FLAGS} - ) - - # Parameters for compiler - if(kbuild_try_compile_KBUILD_COMPILE_DEFINITIONS) - list(APPEND cmake_flags - "-DKBUILD_COMPILE_DEFINITIONS:STRING=${kbuild_try_compile_KBUILD_COMPILE_DEFINITIONS}" - ) - endif(kbuild_try_compile_KBUILD_COMPILE_DEFINITIONS) - - # Other user-defined cmake flags - if(kbuild_try_compile_CMAKE_FLAGS) - - endif(kbuild_try_compile_CMAKE_FLAGS) - - # Possible definition of output variable. - if(kbuild_try_compile_OUTPUT_VARIABLE) - set(output_variable_def "OUTPUT_VARIABLE" "output_tmp") - else(build_try_compile_OUTPUT_VARIABLE) - set(output_variable_def) - endif(kbuild_try_compile_OUTPUT_VARIABLE) - - - try_compile(result_tmp # Result variable(temporary) - "${bindir}" # Binary directory - "${kbuild_aux_dir}/try_compile_project" # Source directory - "kmodule" # Project name - CMAKE_FLAGS # Flags to CMake: - ${cmake_flags} - ${kbuild_try_compile_flags} - ${output_variable_def} - ) - - if(kbuild_try_compile_OUTPUT_VARIABLE) - # Set output variable for the caller - set("${kbuild_try_compile_OUTPUT_VARIABLE}" "${output_tmp}" PARENT_SCOPE) - endif(kbuild_try_compile_OUTPUT_VARIABLE) - # Set result variable for the caller - set("${RESULT_VAR}" "${result_tmp}" PARENT_SCOPE) -endfunction(kbuild_try_compile RESULT_VAR bindir srcfile) - -########### Auxiliary functions for internal use ####################### -# Per-directory tracking for kbuild compiler flags. -# -# Unlike to standard COMPILE_FLAGS, these flags do not include values -# set for parent directories. -# (There is no generic "fill-with-parent's values" mechanism exists -# in cmake). -# -# So, this property has a little sence for the user. -# It exists only for make effect of kbuild_add_definitions() to -# cross "function" scope. -define_property(DIRECTORY PROPERTY KBUILD_COMPILE_FLAGS - BRIEF_DOCS "Compiler flags used by Kbuild system added in this directory." - FULL_DOCS "Compiler flags used by Kbuild system added in this directory." -) - -# Per-directory tracking for kbuild include directories. -# -# Unlike to standard INCLUDE_DIRECTORIES, these ones do not include values -# set for parent directories. -# (There is no generic "fill-with-parent's values" mechanism exists -# in cmake). -# -# So, this property has a little sence for the user. -# It exists only for make effect of kbuild_include_directories() to -# cross "function" scope. -define_property(DIRECTORY PROPERTY KBUILD_INCLUDE_DIRECTORIES - BRIEF_DOCS "Include directories used by Kbuild system; added in this directory." - FULL_DOCS "Include directories used by Kbuild system; added in this directory." -) - - -# Parameters below are set externally only in try_compile() for subproject, -# which include this file. -# No need to cache them as try_compile() project is not configured by the user. - -# Real top-level source directory. -if(NOT KBUILD_REAL_SOURCE_DIR) - set(KBUILD_REAL_SOURCE_DIR ${CMAKE_SOURCE_DIR}) -endif(NOT KBUILD_REAL_SOURCE_DIR) -# Real top-level binary directory. -if(NOT KBUILD_REAL_BINARY_DIR) - set(KBUILD_REAL_BINARY_DIR ${CMAKE_BINARY_DIR}) -endif(NOT KBUILD_REAL_BINARY_DIR) - -# These flags are passed to the 'make' when compile kernel module. -set(kbuild_additional_make_flags) -# These CMake flags will be passed to try_compile() subproject. -set(kbuild_try_compile_flags - "-DKBUILD_REAL_SOURCE_DIR=${KBUILD_REAL_SOURCE_DIR}" - "-DKBUILD_REAL_BINARY_DIR=${KBUILD_REAL_BINARY_DIR}" -) - -# ARCH and CROSS_COMPILE are passed to submake only when non-empty. -if(ARCH) - list(APPEND kbuild_additional_make_flags "ARCH=${ARCH}") - list(APPEND kbuild_try_compile_flags "-DARCH=${ARCH}") -endif(ARCH) -if(CROSS_COMPILE) - list(APPEND kbuild_additional_make_flags "CROSS_COMPILE=${CROSS_COMPILE}") - list(APPEND kbuild_try_compile_flags "-DCROSS_COMPILE=${CROSS_COMPILE}") -endif(CROSS_COMPILE) - -# List of targets created with kmodule_add_module() without -# 'IMPORTED' option. -# -# This list is traversed in kmodule_finalize_linking() for -# create 'Kbuild' files. -# -# Note, that this list does not contain all defined kernel modules, -# so property normally shouldn't be used by outer code. -define_property(GLOBAL PROPERTY KMODULE_TARGETS - BRIEF_DOCS "List of kernel module targets configured for build" - FULL_DOCS "List of kernel module targets configured for build" -) - -# CMAKE_CURRENT_BINARY_DIR at the moment, when kbuild_add_module() is issued. -define_property(TARGET PROPERTY KMODULE_BINARY_DIR - BRIEF_DOCS "CMAKE_CURRENT_BINARY_DIR where module is built." - FULL_DOCS "CMAKE_CURRENT_BINARY_DIR where module is built." -) - -# List of object files, used for build kernel module. -# -# List may be empty in case of simple build, when target module has same -# name as its only source. -# -# This is internal property for configure 'Kbuild' file. -define_property(TARGET PROPERTY KMODULE_OBJ_SOURCES - BRIEF_DOCS "Object source files for build kernel module." - FULL_DOCS "Object source files for build kernel module." -) - -# Compiler flags, added with kbuild_add_definitions() -# -# Note, that KBUILD_C_FLAGS* are not included here. -# -# This is internal property for configure 'Kbuild' file. -define_property(TARGET PROPERTY KMODULE_COMPILE_FLAGS - BRIEF_DOCS "Additional compile flags for build kernel module." - FULL_DOCS "Additional compile flags for build kernel module." -) - -# Include directories, added with kbuild_include_directories(). -# -# This is internal property for configure 'Kbuild' file. -define_property(TARGET PROPERTY KMODULE_COMPILE_FLAGS - BRIEF_DOCS "Additional compile flags for build kernel module." - FULL_DOCS "Additional compile flags for build kernel module." -) - - -# List of symvers files, added by kbuild_link_module(). -# -# This is internal property for configure 'Kbuild' file. -define_property(TARGET PROPERTY KMODULE_DEPEND_SYMVERS - BRIEF_DOCS "Symvers files this module depends on." - FULL_DOCS "Symvers files this module depends on." -) - -# Constants for internal filenames. -set(_kbuild_symvers "Module.symvers") - -# copy_source_to_binary_dir( ) -# -# Helper for the building kernel module. -# -# Make sure that given source file is inside current binary dir. -# That place is writable and has some "uniqeness" garantee for generate -# auxiliary files during build process. -# -# If already inside current binary dir, do nothing and -# set variable to itself. -# -# Otherwise create rule for copy source into "nice" place inside -# current binary dir and set pointed to that place. -function(copy_source_to_binary_dir source new_source_var) - is_path_inside_dir(is_in_current_binary ${CMAKE_CURRENT_BINARY_DIR} "${source}") - if(is_in_current_binary) - # Source is already placed where we want. - set(${new_source_var} "${source}" PARENT_SCOPE) - else(is_in_current_binary) - # Base directory from which count relative source path. - # By default, it is root directory. - set(base_dir "/") - # Try "nicer" base directories. - foreach(d - ${KBUILD_REAL_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${KBUILD_REAL_SOURCE_DIR} - ) - is_path_inside_dir(is_in_d ${d} "${source}") - if(is_in_d) - set(base_dir ${d}) - break() - endif(is_in_d) - endforeach(d) - # Copy source into same relativ dir, but inside current binary one. - file(RELATIVE_PATH source_rel "${base_dir}" "${source}") - set(new_source "${CMAKE_CURRENT_BINARY_DIR}/${source_rel}") - get_filename_component(new_source_dir ${new_source} PATH) - file(MAKE_DIRECTORY "${new_source_dir}") - rule_copy_file("${new_source}" "${source}") - # Return path to the new source. - set(${new_source_var} "${new_source}" PARENT_SCOPE) - endif(is_in_current_binary) -endfunction(copy_source_to_binary_dir source new_source_var) - -# _get_per_build_var(RESULT_VAR variable) -# -# Return value of per-build variable. -macro(_get_per_build_var RESULT_VAR variable) - if(CMAKE_BUILD_TYPE) - string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type_uppercase) - set(${RESULT_VAR} "${${variable}_${_build_type_uppercase}}") - else(CMAKE_BUILD_TYPE) - set(${RESULT_VAR}) - endif(CMAKE_BUILD_TYPE) -endmacro(_get_per_build_var RESULT_VAR variable) - -# _string_join(sep RESULT_VAR str1 str2) -# -# Join strings and using as glue. -# -# Note, that precisely 2 string are joined, not a list of strings. -# This prevents automatic replacing of ';' inside strings while parsing arguments. -macro(_string_join sep RESULT_VAR str1 str2) - if("${str1}" STREQUAL "") - set("${RESULT_VAR}" "${str2}") - elseif("${str2}" STREQUAL "") - set("${RESULT_VAR}" "${str1}") - else("${str1}" STREQUAL "") - set("${RESULT_VAR}" "${str1}${sep}${str2}") - endif("${str1}" STREQUAL "") -endmacro(_string_join sep RESULT_VAR str1 str2) -# _build_get_directory_property_chained(RESULT_VAR []) -# -# Return list of all values for given property in the current directory -# and all parent directories. -# -# If is given, it is used as glue for join values. -# By default, cmake list separator (';') is used. -function(_get_directory_property_chained RESULT_VAR property_name) - set(sep ";") - foreach(arg ${ARGN}) - set(sep "${arg}") - endforeach(arg ${ARGN}) - set(result "") - set(d "${CMAKE_CURRENT_SOURCE_DIR}") - while(NOT "${d}" STREQUAL "") - get_property(p DIRECTORY "${d}" PROPERTY "${property_name}") - # debug - # message("Property ${property_name} for directory ${d}: '${p}'") - _string_join("${sep}" result "${p}" "${result}") - # message("Intermediate result: '${result}'") - get_property(d DIRECTORY "${d}" PROPERTY PARENT_DIRECTORY) - endwhile(NOT "${d}" STREQUAL "") - set("${RESULT_VAR}" "${result}" PARENT_SCOPE) -endfunction(_get_directory_property_chained RESULT_VAR property_name) - -# _kbuild_module_clean_files(module_name -# [C_SOURCE c_source_noext_abs ...] -# [ASM_SOURCE asm_source_noext_abs ...] -# [SHIPPED_SOURCE shipped_source_noext_abs ...]) -# -# Tell CMake that intermediate files, created by kbuild system, -# should be cleaned with 'make clean'. -function(_kbuild_module_clean_files module_name) - cmake_parse_arguments(kbuild_module_clean "" "" "C_SOURCE;ASM_SOURCE;SHIPPED_SOURCE" ${ARGN}) - if(kbuild_module_clean_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unparsed arguments") - endif(kbuild_module_clean_UNPARSED_ARGUMENTS) - - # List common files (names only) for cleaning - set(common_files_names - ".tmp_versions" # Directory - "modules.order" - "Module.markers" - ) - # List module name-depending files (extensions only) for cleaning - set(name_files_ext - ".o" - ".mod.c" - ".mod.o" - ) - # Same but for the files with names starting with a dot ('.'). - set(name_files_dot_ext - ".ko.cmd" - ".mod.o.cmd" - ".o.cmd" - ) - # List source name-depending files (extensions only) for cleaning - set(source_name_files_ext - ".o" - ) - # Same but for the files with names starting with a dot ('.') - set(source_name_files_dot_ext - ".o.cmd" - ".o.d" # This file is created in case of unsuccessfull build - ) - - # Now collect all sort of files into list - set(files_list) - - foreach(name ${common_files_names}) - list(APPEND files_list "${CMAKE_CURRENT_BINARY_DIR}/${name}") - endforeach(name ${common_files_names}) - - foreach(ext ${name_files_ext}) - list(APPEND files_list - "${CMAKE_CURRENT_BINARY_DIR}/${module_name}${ext}") - endforeach(ext ${name_files_ext}) - - foreach(ext ${name_files_dot_ext}) - list(APPEND files_list - "${CMAKE_CURRENT_BINARY_DIR}/.${module_name}${ext}") - endforeach(ext ${name_files_ext}) - - # All the types of sources are processed in a similar way - foreach(obj_source_noext_abs ${kbuild_module_clean_C_SOURCE} - ${kbuild_module_clean_ASM_SOURCE} ${kbuild_module_clean_SHIPPED_SOURCE}) - - get_filename_component(dir ${obj_source_noext_abs} PATH) - get_filename_component(name ${obj_source_noext_abs} NAME) - foreach(ext ${source_name_files_ext}) - list(APPEND files_list "${dir}/${name}${ext}") - endforeach(ext ${source_name_files_ext}) - foreach(ext ${source_name_files_dot_ext}) - list(APPEND files_list "${dir}/.${name}${ext}") - endforeach(ext ${source_name_files_ext}) - endforeach(obj_source_noext_abs) - # Tell CMake that given files should be cleaned. - set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${files_list}") -endfunction(_kbuild_module_clean_files module_name) - -# parse_install_arguments(prefix args..) -# -# Helper for parse arguments for install-like command. -# -# All arguments before the first keyword are classified as GLOBAL_ARGUMENTS -# and stored into list ${prefix}_GLOBAL_ARGUMENTS. -# -# describe possible keywords denoting section type. -# At most one section may exist for every type. -# Special type ALL means generic section. -# -# , and describe -# all keywords inside section. -# Values corresponded to these keywords are stored under -# __*. -# Note, that unlike to cmake_parse_arguments(), all arguments inside -# section definition should be either keyword or its value(s). -# Additionally, _ is set to TRUE for every -# encountered section and _sections contains list of such sections. -# -# If non section is currently active, the first section keyword starts -# special generic section. Definitions for this section are stored as -# for section of type ALL. -# If such section exists, it should be the only section. -# -# Function is generic, but currently is used only there. -function(parse_install_arguments prefix section_types options one_value_keywords multiple_value_keywords) - set(all_keywords ${section_types} ${options} ${one_value_keywords} ${multiple_value_keywords}) - # Type of the currently parsed section('ALL' for ALL section). - set(current_section_type) - # Active section-related keyword for current section. - set(current_section_keyword) - # Classification for @_current_section_keyword: - # 'OPTION', 'ONE' or 'MULTY'. - set(current_section_keyword_type) - - # Clean all previous keyword values. - set("pia_GLOBAL_ARGUMENTS") - foreach(section_type "ALL" ${section_types}) - set(pia_${section_type} "FALSE") - foreach(opt ${options}) - set("pia_${section_type}_${opt}" "FALSE") - endforeach(opt ${options}) - foreach(keyword ${one_value_keywords} ${multiple_value_keywords}) - set("pia_${section_type}_${keyword}") - endforeach(keyword ${one_value_keywords} ${multiple_value_keywords}) - endforeach(section_type "ALL" ${section_types}) - set("pia_sections") - - foreach(arg ${ARGN}) - list(FIND all_keywords ${arg} keyword_index) - if(keyword_index EQUAL "-1") - if(current_section_type) - if(NOT current_section_keyword) - message(FATAL_ERROR "In section ${current_section_type} argument ${arg} does not belong to any keyword.") - endif(NOT current_section_keyword) - if(current_section_keyword_type STREQUAL "ONE") - set("pia_${current_section_type}_${current_section_keyword}" "${arg}") - set(current_section_keyword "") - else(current_section_keyword_type STREQUAL "ONE") - list(APPEND "pia_${current_section_type}_${current_section_keyword}" "${arg}") - endif(current_section_keyword_type STREQUAL "ONE") - else(current_section_type) - list(APPEND "pia_GLOBAL_ARGUMENTS" "${arg}") - endif(current_section_type) - else(keyword_index EQUAL "-1") - if(current_section_type AND current_section_keyword AND current_section_keyword_type STREQUAL "ONE") - message(FATAL_ERROR "Keyword ${arg} found while value for one-value-option ${current_section_keyword} expected.") - endif(current_section_type AND current_section_keyword AND current_section_keyword_type STREQUAL "ONE") - list(FIND section_types "${arg}" section_type_index) - if(section_type_index EQUAL "-1") - if(NOT current_section_type) - set(current_section_type "ALL") - set("pia_${current_section_type}" "TRUE") - list(APPEND "pia_sections" "${current_section_type}") - endif(NOT current_section_type) - list(FIND options ${arg} option_index) - if(option_index EQUAL "-1") - set(current_section_keyword ${arg}) - list(FIND one_value_keywords ${current_section_keyword} one_index) - if(one_index EQUAL "-1") - set(current_section_keyword_type "MULTY") - else(one_index EQUAL "-1") - set(current_section_keyword_type "ONE") - endif(one_index EQUAL "-1") - set("pia_${current_section_type}_${current_section_keyword}") - else(option_index EQUAL "-1") - set("${prefix}_${current_section_type}_${current_section_keyword}" "TRUE") - set(current_section_keyword_type) - endif(option_index EQUAL "-1") - else(section_type_index EQUAL "-1") - if("pia_ALL") - message(FATAL_ERROR "Generic section should be the only section defined") - endif("pia_ALL") - set(current_section_type "${arg}") - if("pia_${current_section_type}") - message(FATAL_ERROR "Section ${current_section_type} is defined twice.") - endif("pia_${current_section_type}") - set("pia_${current_section_type}" "TRUE") - list(APPEND "pia_sections" "${current_section_type}") - # Current keyword is initially undefined for such section. - set(current_section_keyword) - endif(section_type_index EQUAL "-1") - endif(keyword_index EQUAL "-1") - endforeach(arg ${ARGN}) - - # propagate the result variables to the caller - set("${prefix}_GLOBAL_ARGUMENTS" ${pia_GLOBAL_ARGUMENTS} PARENT_SCOPE) - foreach(section_type "ALL" ${section_types}) - set(${prefix}_${section_type} ${pia_${section_type}} PARENT_SCOPE) - foreach(keyword ${options} ${one_value_keywords} ${multiple_value_keywords}) - set("${prefix}_${section_type}_${keyword}" ${pia_${section_type}_${keyword}} PARENT_SCOPE) - endforeach(keyword ${options} ${one_value_keywords} ${multiple_value_keywords}) - endforeach(section_type "ALL" ${section_types}) - set("${prefix}_sections" ${pia_sections} PARENT_SCOPE) -endfunction(parse_install_arguments prefix section_types options one_value_keywords multiple_value_keywords) diff --git a/cmake_targets/tools/MODULES/kmodule.cmake b/cmake_targets/tools/MODULES/kmodule.cmake deleted file mode 100755 index 2912ac115a..0000000000 --- a/cmake_targets/tools/MODULES/kmodule.cmake +++ /dev/null @@ -1,539 +0,0 @@ -set(kmodule_this_module_dir "${CMAKE_SOURCE_DIR}/cmake/modules/") -set(kmodule_test_sources_dir "${CMAKE_SOURCE_DIR}/cmake/kmodule_sources") - -set(kmodule_function_map_file "") -if (CMAKE_CROSSCOMPILING) - if (KEDR_SYSTEM_MAP_FILE) - set (kmodule_function_map_file "${KEDR_SYSTEM_MAP_FILE}") - else (KEDR_SYSTEM_MAP_FILE) -# KEDR_SYSTEM_MAP_FILE is not specified, construct the default path -# to the symbol map file. - set (kmodule_function_map_file - "${KEDR_ROOT_DIR}/boot/System.map-${KBUILD_VERSION_STRING}" - ) - endif (KEDR_SYSTEM_MAP_FILE) -endif (CMAKE_CROSSCOMPILING) - -# List of unreliable functions, that is, the functions that may be -# be exported and mentioned in System.map but still cannot be used -# because no header provides their declarations. -set(unreliable_functions_list - "__kmalloc_node" - "kmem_cache_alloc_node" - "kmem_cache_alloc_node_notrace" - "kmem_cache_alloc_node_trace" -) - -# kmodule_is_function_exist(function_name RESULT_VAR) -# Verify, whether given function exist in the kernel space on the current system. -# RESULT_VAR is TRUE, if function_name exist in the kernel space, FALSE otherwise. -# RESULT_VAR is cached. - -function(kmodule_is_function_exist function_name RESULT_VAR) - check_begin("Looking for ${function_name} in the kernel") - if(NOT DEFINED ${RESULT_VAR}) - check_try() - execute_process( - COMMAND sh "${kmodule_this_module_dir}/kmodule_files/scripts/lookup_kernel_function.sh" - ${function_name} ${kmodule_function_map_file} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - RESULT_VARIABLE kmodule_is_function_exist_result - OUTPUT_QUIET) - - if (kmodule_is_function_exist_result EQUAL 0) - list(FIND unreliable_functions_list ${function_name} unreliable_function_index) - if(unreliable_function_index GREATER -1) - # Additional verification for unreliable function - kbuild_try_compile(kmodule_function_is_exist_reliable - "${CMAKE_BINARY_DIR}/check_unreliable_functions/${function_name}" - "${kmodule_test_sources_dir}/check_unreliable_functions/${function_name}.c" - ) - if(NOT kmodule_function_is_exist_reliable) - set(kmodule_is_function_exist_result 1) - endif(NOT kmodule_function_is_exist_reliable) - endif(unreliable_function_index GREATER -1) - endif(kmodule_is_function_exist_result EQUAL 0) - - if (kmodule_is_function_exist_result EQUAL 0) - set(${RESULT_VAR} "TRUE" CACHE INTERNAL "Does ${function_name} exist in the kernel?") - elseif(kmodule_is_function_exist_result EQUAL 1) - set(${RESULT_VAR} "FALSE" CACHE INTERNAL "Does ${function_name} exist in the kernel?") - else(kmodule_is_function_exist_result EQUAL 0) - message(FATAL_ERROR -"Cannot determine whether function '${function_name}' exists in the kernel" - ) - endif(kmodule_is_function_exist_result EQUAL 0) - endif(NOT DEFINED ${RESULT_VAR}) - set_bool_string(check_result "found" "not found" ${${RESULT_VAR}}) - check_end(${check_result}) -endfunction(kmodule_is_function_exist function_name RESULT_VAR) - -# Creates the list of functions that actually exist on the -# current system. -# -# kmodule_configure_kernel_functions(output_list -# {[REQUIRED | OPTIONAL] {func | ONE_OF_LIST}} ...) -# -# ONE_OF_LIST := ONE_OF_BEGIN {func ...} ONE_OF_END -# -# There are 2 modes of function lookup: -# OPTIONAL - if the function doesn't exist, it is silently ignored. -# REQUIRED - if the function doesn't exist, FATAL_ERROR message is printed. -# -# Initial mode is REQUIRED, and it can be changed at any time by REQUIRED -# and OPTIONAL keywords. -# -# ONE_OF_BEGIN/ONE_OF_END determine a section for which no more than one -# function among all listed there should exist. FATAL_ERROR message is -# printed otherwise. When mode is REQUIRED, precisely one function must -# exist. -# Inside this section other keywords must not be used (even another -# ONE_OF_BEGIN). - -function(kmodule_configure_kernel_functions output_list) - set(kmodule_configure_kernel_functions_mode "REQUIRED") - set(kmodule_configure_kernel_functions_one_of_section "FALSE") - set(output_list_tmp) - set(${output_list}) - foreach(arg ${ARGN}) - if(arg STREQUAL "REQUIRED" OR arg STREQUAL "OPTIONAL") - if(kmodule_configure_kernel_functions_one_of_section) - message(FATAL_ERROR -"Inside ONE_OF_BEGIN/ONE_OF_END section, other keywords are not allowed." - ) - endif(kmodule_configure_kernel_functions_one_of_section) - set(kmodule_configure_kernel_functions_mode ${arg}) - elseif(arg STREQUAL "ONE_OF_BEGIN") - if(kmodule_configure_kernel_functions_one_of_section) - message(FATAL_ERROR "Nested ONE_OF_BEGIN/ONE_OF_END sections are not allowed.") - endif(kmodule_configure_kernel_functions_one_of_section) - set(kmodule_configure_kernel_functions_one_of_section "TRUE") - set(kmodule_configure_kernel_functions_one_of_section_function) - elseif(arg STREQUAL "ONE_OF_END") - if(NOT kmodule_configure_kernel_functions_one_of_section) - message(FATAL_ERROR "ONE_OF_END without ONE_OF_BEGIN is not allowed.") - endif(NOT kmodule_configure_kernel_functions_one_of_section) - if(kmodule_configure_kernel_functions_one_of_section_function) - list(APPEND output_list_tmp ${kmodule_configure_kernel_functions_one_of_section_function}) - else(kmodule_configure_kernel_functions_one_of_section_function) - if(kmodule_configure_kernel_functions_mode STREQUAL "REQUIRED") - message(FATAL_ERROR -"None of the functions listed in ONE_OF section exist in the kernel but it is required." - ) - endif(kmodule_configure_kernel_functions_mode STREQUAL "REQUIRED") - endif(kmodule_configure_kernel_functions_one_of_section_function) - set(kmodule_configure_kernel_functions_one_of_section "FALSE") - else(arg STREQUAL "REQUIRED" OR arg STREQUAL "OPTIONAL") - set(kmodule_func_varname _KMODULE_IS_${arg}_EXIST) - kedr_find_function(${arg} ${kmodule_func_varname}) - if(kmodule_configure_kernel_functions_one_of_section) - if(${kmodule_func_varname}) - if(kmodule_configure_kernel_functions_one_of_section_function) - message(FATAL_ERROR "Two functions from ONE_OF sections exist in the kernel.") - else(kmodule_configure_kernel_functions_one_of_section_function) - set(kmodule_configure_kernel_functions_one_of_section_function ${arg}) - endif(kmodule_configure_kernel_functions_one_of_section_function) - endif(${kmodule_func_varname}) - else(kmodule_configure_kernel_functions_one_of_section) - if(${kmodule_func_varname}) - list(APPEND output_list_tmp ${arg}) - else(${kmodule_func_varname}) - if(kmodule_configure_kernel_functions_mode STREQUAL "REQUIRED") - message(FATAL_ERROR "Function ${arg} is not found in the kernel but it is required.") - endif(kmodule_configure_kernel_functions_mode STREQUAL "REQUIRED") - endif(${kmodule_func_varname}) - endif(kmodule_configure_kernel_functions_one_of_section) - endif(arg STREQUAL "REQUIRED" OR arg STREQUAL "OPTIONAL") - endforeach(arg ${ARGN}) - if(kmodule_configure_kernel_functions_one_of_section) - message(FATAL_ERROR "Found ONE_OF_BEGIN without ONE_OF_END") - endif(kmodule_configure_kernel_functions_one_of_section) - set(${output_list} ${output_list_tmp} PARENT_SCOPE) -endfunction(kmodule_configure_kernel_functions output_list) - -############################################################################ -# Utility macros to check for particular features. If the particular feature -# is supported, the macros will set the corresponding variable to TRUE, -# otherwise - to FALSE (the name of variable is mentioned in the comments -# for the macro). -############################################################################ - -# Check if the system has everything necessary to build at least simple -# kernel modules. -# The macro sets variable 'MODULE_BUILD_SUPPORTED'. -macro(check_module_build) - check_begin("Checking if kernel modules can be built on this system") - if (NOT MODULE_BUILD_SUPPORTED) - check_try() - kbuild_try_compile(module_build_supported_impl - "${CMAKE_BINARY_DIR}/check_module_build" - "${kmodule_test_sources_dir}/check_module_build/module.c" - ) - set_bool_string(MODULE_BUILD_SUPPORTED "yes" "no" ${module_build_supported_impl} - CACHE INTERNAL "Can kernel modules be built on this system?" - ) - endif (NOT MODULE_BUILD_SUPPORTED) - - check_end("${MODULE_BUILD_SUPPORTED}") - - if (NOT MODULE_BUILD_SUPPORTED) - message(FATAL_ERROR -"There are problems with building kernel modules on this system. " -"Please check that the appropriate kernel headers and build tools " -"are installed." - ) - endif (NOT MODULE_BUILD_SUPPORTED) -endmacro(check_module_build) - -# Check if reliable stack trace information can be obtained. -# This is the case, for example, if the kernel is compiled with support -# for frame pointers and/or stack unwind on. -# The macro sets variable 'STACK_TRACE_RELIABLE'. -macro(check_stack_trace) - check_begin("Checking if stack trace information is reliable") - if (NOT DEFINED STACK_TRACE_RELIABLE) - check_try() - kbuild_try_compile(stack_trace_reliable_impl - "${CMAKE_BINARY_DIR}/check_stack_trace" - "${kmodule_test_sources_dir}/check_stack_trace/module.c" - ) - set_bool_string(STACK_TRACE_RELIABLE "yes" "no" ${stack_trace_reliable_impl} - CACHE INTERNAL "Are stack traces reliable on this system?") - endif (NOT DEFINED STACK_TRACE_RELIABLE) - check_end("${STACK_TRACE_RELIABLE}") - - if (NOT STACK_TRACE_RELIABLE) - message ("\n[WARNING]\n" - "It looks like reliable stack traces cannot be obtained on this system.\n" - "The output of KEDR-based tools like LeakCheck will be less detailed\n" - "(each stack trace shown will contain only one frame).\n" - "If this is not acceptable, you could rebuild the kernel with\n" - "CONFIG_FRAME_POINTER or CONFIG_STACK_UNWIND (if available) set to \"y\"\n" - "and then reconfigure and rebuild KEDR.\n") - endif (NOT STACK_TRACE_RELIABLE) -endmacro(check_stack_trace) - -# Check whether ring buffer is implemented by the kernel. -# Set cache variable RING_BUFFER_IMPLEMENTED according to this checking. -function(check_ring_buffer) - check_begin("Checking if ring buffer is implemented in the kernel") - - if (NOT DEFINED RING_BUFFER_IMPLEMENTED) - check_try() - kbuild_try_compile(ring_buffer_implemented_impl - "${CMAKE_BINARY_DIR}/check_ring_buffer" - "${kmodule_test_sources_dir}/check_ring_buffer/module.c" - ) - - set_bool_string(RING_BUFFER_IMPLEMENTED "yes" "no" "${ring_buffer_implemented_impl}" - CACHE INTERNAL "Whether ring buffer is implemented in the kernel" - ) - endif (NOT DEFINED RING_BUFFER_IMPLEMENTED) - check_end(${RING_BUFFER_IMPLEMENTED}) - - if (NOT RING_BUFFER_IMPLEMENTED) - message("\n[WARNING]\nRing buffer is not supported by the system.\n" - "The tracing facilities as well as call monitoring plugins will not be built.\n" - "If this is not acceptable, you could rebuild the kernel with\n" - "CONFIG_RING_BUFFER set to \"y\" and then reconfigure and rebuild KEDR.\n") - endif (NOT RING_BUFFER_IMPLEMENTED) -endfunction(check_ring_buffer) - -# Check which memory allocator is used by the kernel. -# Set KERNEL_MEMORY_ALLOCATOR to 'slab', 'slub', 'slob' or 'other'. -# -# Some functions in that allocators may have same names, but different signatures. -function(check_allocator) - check_begin("Checking which memory allocator is used by the kernel") - if(NOT DEFINED KERNEL_MEMORY_ALLOCATOR) - check_try() - # Use local variable for detect allocator, - # Cache one will be set at the end - set(allocator "") - if(allocator STREQUAL "") - kbuild_try_compile(is_allocator_slab - "${CMAKE_BINARY_DIR}/check_allocator_slab" - "${kmodule_test_sources_dir}/check_allocator/module.c" - KBUILD_COMPILE_DEFINITIONS "-DIS_ALLOCATOR_SLAB" - ) - if (is_allocator_slab) - set(allocator "slab") - endif (is_allocator_slab) - endif(allocator STREQUAL "") - - if(allocator STREQUAL "") - kbuild_try_compile(is_allocator_slub - "${CMAKE_BINARY_DIR}/check_allocator_slub" - "${kmodule_test_sources_dir}/check_allocator/module.c" - KBUILD_COMPILE_DEFINITIONS "-DIS_ALLOCATOR_SLUB" - ) - if (is_allocator_slub) - set(allocator "slub") - endif (is_allocator_slub) - endif(allocator STREQUAL "") - - if(allocator STREQUAL "") - kbuild_try_compile(is_allocator_slob - "${CMAKE_BINARY_DIR}/check_allocator_slob" - "${kmodule_test_sources_dir}/check_allocator/module.c" - KBUILD_COMPILE_DEFINITIONS "-DIS_ALLOCATOR_SLOB" - ) - if (is_allocator_slob) - set(allocator "slob") - endif (is_allocator_slub) - endif(allocator STREQUAL "") - - if(allocator STREQUAL "") - set(allocator "other") - endif(allocator STREQUAL "") - - set(KERNEL_MEMORY_ALLOCATOR "${allocator}" CACHE INTERNAL - "Memory allocator which is used by the kernel" - ) - endif (NOT DEFINED KERNEL_MEMORY_ALLOCATOR) - check_end("${KERNEL_MEMORY_ALLOCATOR}") -endfunction(check_allocator) - -# Check if 'kfree_rcu' is available in the kernel (it is likely to be -# a macro or an inline). If it is available, we should handle it as -# 'free' in LeakCheck. As KEDR cannot normally intercept kfree_rcu() -# itself, it needs to intercept call_rcu/call_rcu_sched and check their -# arguments. -# The macro sets variable 'HAVE_KFREE_RCU'. -macro(check_kfree_rcu) - check_begin("Checking if kfree_rcu() is available") - - if (NOT DEFINED HAVE_KFREE_RCU) - check_try() - kbuild_try_compile(have_kfree_rcu_impl - "${CMAKE_BINARY_DIR}/check_kfree_rcu" - "${kmodule_test_sources_dir}/check_kfree_rcu/module.c" - ) - - set_bool_string(HAVE_KFREE_RCU "yes" "no" ${have_kfree_rcu_impl} - CACHE INTERNAL "Is kfree_rcu() available?" - ) - endif () - check_end("${HAVE_KFREE_RCU}") -endmacro(check_kfree_rcu) -############################################################################ - -# Check if posix_acl_from_xattr() accepts struct user_namespace as the -# first argument. -# The macro sets variable 'POSIX_ACL_XATTR_HAS_USER_NS'. -macro(check_xattr_user_ns) - check_begin("Checking if posix_acl_from_xattr() has struct user_namespace * argument") - if (NOT DEFINED POSIX_ACL_XATTR_HAS_USER_NS) - check_try() - kbuild_try_compile(have_xattr_user_ns_impl - "${CMAKE_BINARY_DIR}/check_xattr_user_ns" - "${kmodule_test_sources_dir}/check_xattr_user_ns/module.c" - ) - - set_bool_string(POSIX_ACL_XATTR_HAS_USER_NS "yes" "no" ${have_xattr_user_ns_impl} - CACHE INTERNAL "Does posix_acl_from_xattr() have struct user_namespace argument?" - ) - endif () - check_end("${POSIX_ACL_XATTR_HAS_USER_NS}") -endmacro(check_xattr_user_ns) -############################################################################ - -# Check if hlist_for_each_entry*() macros accept only 'type *pos' argument -# rather than both 'type *tpos' and 'hlist_node *pos' as the loop cursors. -# The macro sets variable 'HLIST_FOR_EACH_ENTRY_POS_ONLY'. -macro(check_hlist_for_each_entry) - check_begin("Checking the signatures of hlist_for_each_entry*() macros") - if (NOT DEFINED HLIST_FOR_EACH_ENTRY_POS_ONLY) - check_try() - kbuild_try_compile(pos_only_impl - "${CMAKE_BINARY_DIR}/check_hlist_for_each_entry" - "${kmodule_test_sources_dir}/check_hlist_for_each_entry/module.c" - ) - set_bool_string(HLIST_FOR_EACH_ENTRY_POS_ONLY "yes" "no" ${pos_only_impl} - CACHE INTERNAL - "Do hlist_for_each_entry*() macros have only 'type *pos' to use as a loop cursor?" - ) - endif () - set_bool_string(check_result "do not use additional loop cursor" "use additional loop cursor" - ${HLIST_FOR_EACH_ENTRY_POS_ONLY}) - check_end(${check_result}) -endmacro(check_hlist_for_each_entry) -############################################################################ - -# Check if 'random32' is available in the kernel. -# The macro sets variable 'KEDR_HAVE_RANDOM32'. -macro(check_random32) - check_begin("Checking if random32() is available") - if (NOT DEFINED KEDR_HAVE_RANDOM32) - check_try() - kbuild_try_compile(have_random32_impl - "${CMAKE_BINARY_DIR}/check_random32" - "${kmodule_test_sources_dir}/check_random32/module.c" - ) - set_bool_string(KEDR_HAVE_RANDOM32 "yes" "no" "${have_random32_impl}" - CACHE INTERNAL "Is random32() available?" - ) - endif () - check_end("${KEDR_HAVE_RANDOM32}") -endmacro(check_random32) -############################################################################ - -# The payload modules should call kedr_find_function() for each kernel -# function they would like to process. If the function is not known -# to KEDR (absent from the "function database", see "functions/" directory), -# kedr_find_function() issues a fatal error. -# -# 'func_name' is the name of the function, -# 'found_var' is the name of the output variable (the variable will evaluate -# as "true" if found, as "false" otherwise). -function (kedr_find_function func_name found_var) - if (NOT DEFINED KEDR_DATA_FILE_${func_name}) - message(FATAL_ERROR "Unsupported function: ${func_name}") - endif (NOT DEFINED KEDR_DATA_FILE_${func_name}) - - # OK, known function. - kmodule_is_function_exist(${func_name} ${found_var}) - if (${found_var}) - # Mark the function as used by at least one payload module. - # This can be used when preparing the tests for call interception. - # The actual value does not matter, it only matters that this - # variable is defined. - set(KEDR_FUNC_USED_${func_name} "yes" CACHE INTERNAL - "Is kernel function ${func_name} used by any payload module?") - set(${found_var} "${${found_var}}" PARENT_SCOPE) - else () - set(${found_var} "NO" PARENT_SCOPE) - endif (${found_var}) -endfunction (kedr_find_function func_name found_var) - -# Returns (in ${path_var}) the path to the .data file for the function -# ${func_name}. The function must be present in the system and -# kedr_find_function() must be called for it before kedr_get_data_for_func(). -function (kedr_get_data_for_func func_name path_var) - if (NOT DEFINED KEDR_FUNC_USED_${func_name}) - message(FATAL_ERROR -"Attempt to lookup data for a function that is not marked as used: " - "${func_name}") - endif (NOT DEFINED KEDR_FUNC_USED_${func_name}) - - set(${path_var} "${KEDR_DATA_FILE_${func_name}}" PARENT_SCOPE) -endfunction (kedr_get_data_for_func func_name path_var) - -# kedr_get_header_data_list(list_var func1 [func2 func3 ...]) -# Get the list of paths to the 'header.data' files for the given functions. -# The functions must be present in the system and # kedr_find_function() -# must be called for each of them before kedr_get_header_data_list() is -# called. -# The resulting list is returned in ${list_var}. It will contain at least -# one item. It will not contain duplicates. -function (kedr_get_header_data_list list_var) - set(hdata_list) - foreach (func ${ARGN}) - if (NOT DEFINED KEDR_FUNC_USED_${func}) - message(FATAL_ERROR -"Attempt to lookup header data for a function that is not marked as used: " - "${func}") - endif (NOT DEFINED KEDR_FUNC_USED_${func}) - list(APPEND hdata_list "${KEDR_HEADER_DATA_FILE_${func}}") - endforeach () - list(REMOVE_DUPLICATES hdata_list) - - list(LENGTH hdata_list hdata_list_len) - if (NOT hdata_list_len) - message(FATAL_ERROR - "kedr_get_header_data_list(): BUG: the output list is empty.") - endif (NOT hdata_list_len) - - set(${list_var} ${hdata_list} PARENT_SCOPE) -endfunction (kedr_get_header_data_list list_var) - -# kedr_create_header_rules( -# header_impl_file header_data_file func1 [func2 ...]) -# Create the rules to generate ${header_impl_file} from -# ${header_data_file} and the specific header files for the given -# functions. -function(kedr_create_header_rules header_impl_file header_data_file - functions) - set(hlist_data) - kedr_get_header_data_list(hlist_data ${functions} ${ARGN}) - to_abs_path(hdata_files_abs ${header_data_file} ${hlist_data}) - add_custom_command(OUTPUT ${header_impl_file} - COMMAND cat ${hdata_files_abs} > ${header_impl_file} - DEPENDS ${hdata_files_abs} - ) -endfunction(kedr_create_header_rules header_impl_file header_data_file - functions) - -# kedr_create_data_rules(func) -# Create the rules to generate ${func}_impl.data from -# ${func}.data (contains processing instructions specific to the current -# payload) and the .data file from "func_db" (contains function signature). -function(kedr_create_data_rules func) - set(func_db_data_file) - kedr_get_data_for_func(${func} func_db_data_file) - - set(func_proc_data_file) - to_abs_path(func_proc_data_file ${func}.data) - - add_custom_command(OUTPUT "${func}_impl.data" - COMMAND printf "\"[group]\\n\"" > "${func}_impl.data" - COMMAND grep -E -v '\\[group\\]' - "${func_db_data_file}" >> "${func}_impl.data" - COMMAND printf "\"\\n\"" >> "${func}_impl.data" - COMMAND grep -E -v '\\[group\\]' - "${func_proc_data_file}" >> "${func}_impl.data" - DEPENDS - "${func_proc_data_file}" - "${func_db_data_file}" - ) -endfunction(kedr_create_data_rules func) - -# kedr_create_payload_module(module_name payload_data_file template_dir) -# Create the rules to build a payload module with the given name. -# 'payload_data_file' defines how the kernel functions are to be processed -# by this payload module. -# 'template_dir' - path to the direcotry containing the templates to be used -# to prepare the source code of the module from 'payload_data_file'. -function(kedr_create_payload_module module_name payload_data_file - template_dir) - - # Rules to build the module - kbuild_add_module(${module_name} - "payload.c" - "functions_support.c" - ) - kbuild_link_module(${module_name} kedr) - - # Rules to obtain the source files of the module - kedr_generate("payload.c" ${payload_data_file} "${template_dir}") - kedr_generate("functions_support.c" ${payload_data_file} "${KEDR_GEN_TEMPLATES_DIR}/functions_support.c") -endfunction(kedr_create_payload_module module_name payload_data_file - template_dir) - -# kedr_create_payload_data(payload_data_file func1 [func2 ...]) -# Create .data files and the header data files for the functions and prepare -# the main .data file (${payload_data_file}) for the payload module. -function(kedr_create_payload_data header_data_file payload_data_file - functions) - set(header_impl_file "header_impl.data") - set(functions_data) - - foreach(func ${functions} ${ARGN}) - list(APPEND functions_data "${func}_impl.data") - kedr_create_data_rules(${func}) - endforeach(func ${functions} ${ARGN}) - - kedr_create_header_rules(${header_impl_file} ${header_data_file} - ${functions} ${ARGN}) - - to_abs_path(payload_data_file_abs ${payload_data_file}) - to_abs_path(source_files_abs ${header_impl_file} ${functions_data}) - - set(payload_data_file_abs "${CMAKE_CURRENT_BINARY_DIR}/${payload_data_file}") - add_custom_command(OUTPUT ${payload_data_file_abs} - COMMAND cat ${source_files_abs} > ${payload_data_file_abs} - DEPENDS ${source_files_abs} - ) -endfunction(kedr_create_payload_data header_data_file payload_data_file - functions) -############################################################################ diff --git a/cmake_targets/tools/example_oaisim_enb_ue_mme_virtual.txt b/cmake_targets/tools/example_oaisim_enb_ue_mme_virtual.txt deleted file mode 100755 index 805d121e6d..0000000000 --- a/cmake_targets/tools/example_oaisim_enb_ue_mme_virtual.txt +++ /dev/null @@ -1,98 +0,0 @@ -#/* -# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -# * contributor license agreements. See the NOTICE file distributed with -# * this work for additional information regarding copyright ownership. -# * The OpenAirInterface Software Alliance licenses this file to You under -# * the OAI Public License, Version 1.1 (the "License"); you may not use this file -# * except in compliance with the License. -# * You may obtain a copy of the License at -# * -# * http://www.openairinterface.org/?page_id=698 -# * -# * Unless required by applicable law or agreed to in writing, software -# * distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. -# *------------------------------------------------------------------------------- -# * For more information about the OpenAirInterface (OAI) Software Alliance: -# * contact@openairinterface.org -# */ - -# file example_oaisim_enb_ue_mme_virtual.txt -# brief -# author Lionel Gauthier - -TODO: a document file, PDF for example, with nice pictures, etc -This example shows how to generate and launch enb, 1 ue (NAS still not virtualized in UE) in virtualised mode, mme_gw, hss executables on the same host: - -################ -Configuration -################ -freediameter 1.2.0 (not 1.1.5, 1.1.6,...) has to be installed and patched (done by check_install_oai_software() calling install_freediameter_from_source() in script build_helper) - -Config File: -/etc/hosts must contain the fqdn of the MME and HSS (same since both run on the same host): -(assuming the realm is openair4G.eur) -127.0.0.1 localhost -127.0.1.1 yang.openair4G.eur yang -... - -################ -BUILDING, RUNNING -################ - -Building HSS: -yang@yang:~/openair4G/trunk/cmake_targets$ tools/build_hss -c --connect-to-mme yang.openair4G.eur -t -T --realm openair4G.eur - -Configuring the HSS: -In oai_db (easier for newbies to access HSS database through http://127.0.0.1/phpmyadmin) - In table mmeidentity, enter the record corresponding to your MME: - (idmmeidentity, mmehost, mmerealm) - In table pdn, enter the record allowing an IMSI to connect to an APN - In table users, enter the record corresponding to your USIM card. - -Running the HSS: -yang@yang:~/openair4G/trunk/cmake_targets$ sudo tools/run_hss -g - - - -Building the MME-GW: -yang@yang:~/openair4G/trunk/cmake_targets/tools$ ./build_epc -c -d -t -T --s6a-server - -Configuring the MME-GW: - You can configure in file openair4G/trunk/cmake_targets/tools/epc.local.enb.conf.in the following parameters: - MCC/MNC of your network - SGI interface (outgoing interface of the S/P-GW) - Integrity algorithms, Ciphering algorithms - Please note that DNS addresses are hardcoded in source code (TODO in list). - -Running the MME-GW: -yang@yang:~/openair4G/trunk/cmake_targets/tools$ sudo ./run_epc -l -g -K - - - -Building eNB: -yang@yang:~/openair4G/trunk/cmake_targets$ ./build_oai --oaisim - -Configuring the eNB: - The default configuration file for the eNB is trunk/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf - -Running eNB: -yang@yang:~/openair4G/trunk/cmake_targets$ tools/run_enb_ue_virt_s1 -m /tmp -K /tmp/enb_ue_virt_s1_itti.log - - -Putting some IP UL/DL traffic in the bearer: -ping -s 1000 -m 1 192.168.12.100 -I oip1 - - -################ -Tools available: -############### - -1) itti_analyser (list messages exchanged between protocol layers) -2) xforms (Layer 1) -3) vcd (timing mesurements) - - - diff --git a/cmake_targets/tools/make_agent_cache b/cmake_targets/tools/make_agent_cache deleted file mode 100755 index d2eab20fc0..0000000000 --- a/cmake_targets/tools/make_agent_cache +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -CACHE_DIR=/mnt/oai_agent_cache - -if [ ! -d $CACHE_DIR ]; then - echo "Creating cache dir in $CACHE_DIR" - sudo mkdir $CACHE_DIR -fi - -if grep -qs "$CACHE_DIR" /proc/mounts; then - echo "Agent cache is already mounted" -else - echo "Agent cache was not mounted" - echo "Mounting..." - sudo mount -o size=100m -t tmpfs none "$CACHE_DIR" - if [ $? -eq 0 ]; then - echo "Mount success" - else - echo "Something went wrong with the mount" - fi -fi diff --git a/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch b/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch index 3f953b36d9..6d68225bbf 100644 --- a/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch +++ b/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch @@ -1,5 +1,5 @@ diff --git a/fhi_lib/app/src/common.h b/fhi_lib/app/src/common.h -index ac5f471..b0f7ed1 100644 +index ac5f471..94c2d7c 100644 --- a/fhi_lib/app/src/common.h +++ b/fhi_lib/app/src/common.h @@ -28,7 +28,7 @@ @@ -7,7 +7,7 @@ index ac5f471..b0f7ed1 100644 #include -#define VERSIONX "oran_f_release_v1.0" -+#define VERSIONX "oran_f_release_v1.5" ++#define VERSIONX "oran_f_release_v1.6" #define APP_O_DU 0 #define APP_O_RU 1 @@ -173,18 +173,20 @@ index eccc4ae..a97fdc6 100644 CPP_FLAGS_FULL := $(CPP_FLAGS) $(CPP_COMP) $(INC) $(DEF) CPP_FLAGS_FULL_SNC := $(CPP_FLAGS) $(CPP_COMP_SNC) $(INC) $(DEF) diff --git a/fhi_lib/lib/api/xran_fh_o_du.h b/fhi_lib/lib/api/xran_fh_o_du.h -index bacf597..1dd6d66 100644 +index bacf597..2aeaaae 100644 --- a/fhi_lib/lib/api/xran_fh_o_du.h +++ b/fhi_lib/lib/api/xran_fh_o_du.h -@@ -141,7 +141,7 @@ extern "C" { +@@ -141,8 +141,8 @@ extern "C" { #define XRAN_MAX_SECTIONS_PER_SYM (XRAN_MAX_SECTIONS_PER_SLOT) /**< Max number of different sections in single slot (section may be equal to RB allocation for UE) */ #define XRAN_MIN_SECTIONS_PER_SYM (XRAN_MIN_SECTIONS_PER_SLOT) /**< Min number of different sections in single slot (section may be equal to RB allocation for UE) */ -#define XRAN_MAX_FRAGMENT (4) /**< Max number of fragmentations in single symbol */ +-#define XRAN_MAX_SET_BFWS (64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */ +#define XRAN_MAX_FRAGMENT (6) /**< Max number of fragmentations in single symbol */ - #define XRAN_MAX_SET_BFWS (64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */ ++#define XRAN_MAX_SET_BFWS (1) //(64) /**< Assumed 64Ant, BFP 9bit with 9K jumbo frame */ #define XRAN_MAX_PKT_BURST (448+4) /**< 4x14x8 symbols per ms */ + #define XRAN_N_MAX_BUFFER_SEGMENT XRAN_MAX_PKT_BURST /**< Max number of segments per ms */ @@ -419,6 +419,7 @@ struct xran_io_cfg { uint16_t num_rxq; /**< number of RX queues per VF */ char *dpdk_dev[XRAN_VF_MAX]; /**< VFs devices */ @@ -193,7 +195,15 @@ index bacf597..1dd6d66 100644 int32_t bbdev_mode; /**< DPDK for BBDev */ uint32_t dpdkIoVaMode; /**< IOVA Mode */ uint32_t dpdkMemorySize; /**< DPDK max memory allocation */ -@@ -1193,6 +1194,31 @@ int32_t xran_reg_physide_cb_by_dev_id(void *pHandle, xran_fh_tti_callback_fn Cb, +@@ -713,6 +714,7 @@ struct xran_fh_config { + uint16_t max_sections_per_slot; /**< M-Plane settings for section */ + uint16_t max_sections_per_symbol; /**< M-Plane settings for section */ + int32_t RunSlotPrbMapBySymbolEnable; /**< enable prb mapping by symbol with multisection*/ ++ uint8_t LiteOnIgnoreUPSectionIdEnable; /**< handle LiteOn issue where section id on UP packet is wrongly set to 13. */ + + uint8_t dssEnable; /**< enable DSS (extension-9) */ + uint8_t dssPeriod; /**< DSS pattern period for LTE/NR */ +@@ -1193,6 +1195,31 @@ int32_t xran_reg_physide_cb_by_dev_id(void *pHandle, xran_fh_tti_callback_fn Cb, */ int32_t xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, uint32_t *nSlotIdx, uint64_t *nSecond); @@ -535,7 +545,7 @@ index 08660f3..2bb5187 100644 #include #include diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c -index dc40ad9..5968d01 100644 +index dc40ad9..1b88013 100644 --- a/fhi_lib/lib/src/xran_common.c +++ b/fhi_lib/lib/src/xran_common.c @@ -31,7 +31,10 @@ @@ -549,7 +559,110 @@ index dc40ad9..5968d01 100644 #include #include #include -@@ -714,11 +717,14 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -49,6 +52,8 @@ + #include "xran_printf.h" + #include "xran_mlog_lnx.h" + ++#include "xran_frame_struct.h" ++ + static struct timespec sleeptime = {.tv_nsec = 1E3 }; /* 1 us */ + + extern int32_t first_call; +@@ -529,13 +534,30 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru + if (pRbMap) + { + /** Get the prb_elem_id */ ++ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13 ++ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13 ++ if(0 == p_dev_ctx->LiteOnIgnoreUPSectionIdEnable) { ++ section_id_tmp = prb_elem_id_tmp = sect_id[i]; ++ } else { ++ u_int8_t mixed_ul_sym_start = 0; ++ if (xran_fs_get_slot_type(xran_port, CC_ID[i], tti, XRAN_SLOT_TYPE_SP)) { ++ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID[i], tti); ++ } ++ u_int8_t section_id_tmp = symb_id[i] - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000 ++ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000 ++ //Note for future reference when using MTU 1500 ++ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ } ++ + total_sections=0; + if(pRbMap->prbMap[0].bf_weight.extType == 1) + { + for(idxElm=0 ; idxElm < pRbMap->nPrbElm ; idxElm++) + { + total_sections += pRbMap->prbMap[idxElm].bf_weight.numSetBFWs; +- if(total_sections >= (sect_id[i] + 1)) ++ if(total_sections >= (/*sect_id[i]*/ prb_elem_id_tmp + 1)) + { + prb_elem_id[i] = idxElm; + break; +@@ -544,12 +566,12 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru + } + else + { +- prb_elem_id[i] = sect_id[i]; ++ prb_elem_id[i] = prb_elem_id_tmp; /*sect_id[i];*/ + } + + if (prb_elem_id[i] >= pRbMap->nPrbElm) + { +- print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", sect_id[i], prb_elem_id[i], pRbMap->nPrbElm); ++ print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", /*sect_id[i]*/ section_id_tmp, prb_elem_id[i], pRbMap->nPrbElm); + ret_data[i] = MBUF_FREE; + continue; + } +@@ -615,13 +637,30 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru + if (pRbMap) + { + /** Get the prb_elem_id */ ++ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13 ++ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13 ++ if(0 == p_dev_ctx->LiteOnIgnoreUPSectionIdEnable) { ++ section_id_tmp = prb_elem_id_tmp = sect_id[i]; ++ } else { ++ u_int8_t mixed_ul_sym_start = 0; ++ if (xran_fs_get_slot_type(xran_port, CC_ID[i], tti, XRAN_SLOT_TYPE_SP)) { ++ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID[i], tti); ++ } ++ u_int8_t section_id_tmp = symb_id[i] - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000 ++ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000 ++ //Note for future reference when using MTU 1500 ++ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ } ++ + total_sections=0; + if(pRbMap->prbMap[0].bf_weight.extType == 1) + { + for(idxElm=0 ; idxElm < pRbMap->nPrbElm ; idxElm++) + { + total_sections += pRbMap->prbMap[idxElm].bf_weight.numSetBFWs; +- if(total_sections >= (sect_id[i] + 1)) ++ if(total_sections >= (/*sect_id[i]*/ prb_elem_id_tmp + 1)) + { + prb_elem_id[i] = idxElm; + break; +@@ -630,12 +669,12 @@ int process_mbuf_batch(struct rte_mbuf* pkt_q[], void* handle, int16_t num, stru + } + else + { +- prb_elem_id[i] = sect_id[i]; ++ prb_elem_id[i] = prb_elem_id_tmp; /*sect_id[i];*/ + } + + if (prb_elem_id[i] >= pRbMap->nPrbElm) + { +- print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", sect_id[i], prb_elem_id[i], pRbMap->nPrbElm); ++ print_err("sect_id %d, prb_elem_id %d !=pRbMap->nPrbElm %d\n", /*sect_id[i]*/ section_id_tmp, prb_elem_id[i], pRbMap->nPrbElm); + ret_data[i] = MBUF_FREE; + continue; + } +@@ -714,11 +753,14 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) uint8_t compMeth = 0; uint8_t iqWidth = 0; @@ -564,7 +677,7 @@ index dc40ad9..5968d01 100644 if(first_call == 0) return ret; -@@ -733,9 +739,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -733,9 +775,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) return MBUF_FREE; num_bytes = xran_extract_iq_samples(pkt, &iq_samp_buf, @@ -576,7 +689,7 @@ index dc40ad9..5968d01 100644 if (num_bytes <= 0) { print_err("num_bytes is wrong [%d]\n", num_bytes); -@@ -781,10 +787,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -781,10 +823,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) else { @@ -590,7 +703,7 @@ index dc40ad9..5968d01 100644 #ifndef FCN_ADAPT if(valid_res != 0) { -@@ -807,8 +812,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) +@@ -807,8 +848,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) PrachCfg = &(p_dev_ctx->PrachCPConfig); } @@ -600,7 +713,7 @@ index dc40ad9..5968d01 100644 /* PRACH packet has ruportid = num_eAxc + ant_id */ Ant_ID -= PrachCfg->eAxC_offset; symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] += num_bytes; -@@ -1412,7 +1416,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc +@@ -1412,7 +1452,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc if(XRAN_FILTERINDEX_PRACH_ABC == pPrachCPConfig->filterIdx) { timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu @@ -609,7 +722,7 @@ index dc40ad9..5968d01 100644 timeOffset += 16; } else -@@ -1547,8 +1551,7 @@ int32_t ring_processing_func(void* args) +@@ -1547,8 +1587,7 @@ int32_t ring_processing_func(void* args) for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i++){ for(qi = 0; qi < ctx->rxq_per_port[i]; qi++) { @@ -918,8 +1031,58 @@ index 4acade1..c939edc 100644 if(pCtx){ for(i = 0; i < xran_ports_num; i++){ g_xran_dev_ctx[i] = pCtx; +diff --git a/fhi_lib/lib/src/xran_dev.h b/fhi_lib/lib/src/xran_dev.h +index 0371a53..dd76b49 100644 +--- a/fhi_lib/lib/src/xran_dev.h ++++ b/fhi_lib/lib/src/xran_dev.h +@@ -201,6 +201,7 @@ struct __rte_cache_aligned xran_device_ctx + + int32_t DynamicSectionEna; + int32_t RunSlotPrbMapBySymbolEnable; ++ uint8_t LiteOnIgnoreUPSectionIdEnable; /**< handle LiteOn issue where section id on UP packet is wrongly set to 13. */ + int64_t offset_sec; + int64_t offset_nsec; //offset to GPS time calcuated based on alpha and beta + uint32_t interval_us_local; +diff --git a/fhi_lib/lib/src/xran_frame_struct.c b/fhi_lib/lib/src/xran_frame_struct.c +index fbb1298..44aaf92 100644 +--- a/fhi_lib/lib/src/xran_frame_struct.c ++++ b/fhi_lib/lib/src/xran_frame_struct.c +@@ -519,4 +519,20 @@ int32_t xran_fs_get_symbol_type(uint32_t PortId, int32_t nCellIdx, int32_t nSlot + return xran_fs_slot_symb_type[PortId][nCellIdx][nSfIdxMod][nSymbIdx]; + } + ++uint32_t xran_fs_get_num_dl_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx) ++{ ++ int32_t nSfIdxMod; ++ ++ nSfIdxMod = xran_fs_slot_limit(PortId, nSlotdx) % ((xran_fs_num_slot_tdd_loop[PortId][nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[PortId][nCellIdx]: 1); ++ ++ return xran_fs_num_dl_sym_sp[PortId][nCellIdx][nSfIdxMod]; ++} + ++uint32_t xran_fs_get_num_ul_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx) ++{ ++ int32_t nSfIdxMod; ++ ++ nSfIdxMod = xran_fs_slot_limit(PortId, nSlotdx) % ((xran_fs_num_slot_tdd_loop[PortId][nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[PortId][nCellIdx]: 1); ++ ++ return xran_fs_num_ul_sym_sp[PortId][nCellIdx][nSfIdxMod]; ++} +diff --git a/fhi_lib/lib/src/xran_frame_struct.h b/fhi_lib/lib/src/xran_frame_struct.h +index 7ed0a3a..8e66945 100644 +--- a/fhi_lib/lib/src/xran_frame_struct.h ++++ b/fhi_lib/lib/src/xran_frame_struct.h +@@ -75,6 +75,8 @@ uint32_t xran_fs_slot_limit_init(uint32_t PortId, int32_t tti_interval_us); + uint32_t xran_fs_get_max_slot(uint32_t PortId); + uint32_t xran_fs_get_max_slot_SFN(uint32_t PortId); + int32_t xran_fs_get_symbol_type(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx, int32_t nSymbIdx); ++uint32_t xran_fs_get_num_dl_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx); ++uint32_t xran_fs_get_num_ul_sym_sp(uint32_t PortId, int32_t nCellIdx, int32_t nSlotdx); + + #ifdef __cplusplus + } diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c -index 7c472d7..9da3621 100644 +index 7c472d7..7c7cf91 100644 --- a/fhi_lib/lib/src/xran_main.c +++ b/fhi_lib/lib/src/xran_main.c @@ -35,7 +35,11 @@ @@ -974,7 +1137,7 @@ index 7c472d7..9da3621 100644 beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, port_id, slot_id); + pBufList = &(p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList); -+ struct xran_prb_map *prbMap = pBufList->pBuffers->pData; ++ struct xran_prb_map *prbMap = (struct xran_prb_map *)pBufList->pBuffers->pData; + struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang + beam_id = pPrbElm->nBeamIndex; ret = generate_cpmsg_prach(pHandle, ¶ms, sect_geninfo, mbuf, p_xran_dev_ctx, @@ -985,7 +1148,7 @@ index 7c472d7..9da3621 100644 beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, port_id, slot_id); + pBufList = &(p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList); -+ struct xran_prb_map *prbMap = pBufList->pBuffers->pData; ++ struct xran_prb_map *prbMap = (struct xran_prb_map *)pBufList->pBuffers->pData; + struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang + beam_id = pPrbElm->nBeamIndex; ret = generate_cpmsg_prach(pHandle, ¶ms, sect_geninfo, mbuf, p_xran_dev_ctx, @@ -1550,7 +1713,15 @@ index 7c472d7..9da3621 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -4034,6 +4062,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, +@@ -3754,6 +3782,7 @@ xran_open(void *pHandle, struct xran_fh_config* pConf) + p_xran_dev_ctx->puschMaskSlot = pConf->puschMaskSlot; + p_xran_dev_ctx->DynamicSectionEna = pConf->DynamicSectionEna; + p_xran_dev_ctx->RunSlotPrbMapBySymbolEnable = pConf->RunSlotPrbMapBySymbolEnable; ++ p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable = pConf->LiteOnIgnoreUPSectionIdEnable; + p_xran_dev_ctx->dssEnable = pConf->dssEnable; + p_xran_dev_ctx->dssPeriod = pConf->dssPeriod; + for(i=0; idssPeriod; i++) { +@@ -4034,6 +4063,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, return tti; } @@ -1575,6 +1746,73 @@ index 7c472d7..9da3621 100644 int32_t xran_set_debug_stop(int32_t value, int32_t count) { +@@ -4208,7 +4255,7 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str + int32_t i = 0, j = 0, nPrbElm = 0; + int16_t iqwidth = p_PrbMapIn->prbMap[0].iqWidth; + struct xran_prb_elm *p_prb_elm_src, *p_prb_elm_dst; +- struct xran_prb_elm prbMapTemp[XRAN_NUM_OF_SYMBOL_PER_SLOT]; ++ struct xran_prb_elm prbMapTemp[XRAN_NUM_OF_SYMBOL_PER_SLOT] = {0} ; // Need to initialize to zero for field sec_desc. + int32_t nRBStart_tmp, nRBremain, nStartSymb, nEndSymb, nRBStart, nRBEnd, nRBSize; + // int32_t eth_xran_up_headers_sz = sizeof(struct eth_xran_up_pkt_hdr); + // int32_t nmaxRB = (mtu - eth_xran_up_headers_sz - RTE_PKTMBUF_HEADROOM)/XRAN_PAYLOAD_1_RB_SZ(iqwidth); +@@ -4217,7 +4264,6 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str + if (mtu==9600) + nmaxRB--; //for some reason when mtu is 9600, only 195 RB can be sent, not 196 + +- + memcpy(p_PrbMapOut, p_PrbMapIn, sizeof(struct xran_prb_map)); + for(i = 0; i < XRAN_NUM_OF_SYMBOL_PER_SLOT; i++) + { +@@ -4292,26 +4338,30 @@ int32_t xran_init_PrbMap_by_symbol_from_cfg(struct xran_prb_map* p_PrbMapIn, str + + for(; i < XRAN_NUM_OF_SYMBOL_PER_SLOT; i++) + { +- if((nRBStart == prbMapTemp[i].nRBStart) && (nRBSize == prbMapTemp[i].nRBSize)) +- { +- prbMapTemp[nPrbElm].numSymb++; +- } +- else ++ if((prbMapTemp[i].nRBSize != 0)) + { +- nPrbElm++; +- prbMapTemp[nPrbElm].nStartSymb = prbMapTemp[i].nStartSymb; +- prbMapTemp[nPrbElm].nRBStart = prbMapTemp[i].nRBStart; +- prbMapTemp[nPrbElm].nRBSize = prbMapTemp[i].nRBSize; +- prbMapTemp[nPrbElm].nBeamIndex = prbMapTemp[i].nBeamIndex; +- prbMapTemp[nPrbElm].bf_weight_update = prbMapTemp[i].bf_weight_update; +- prbMapTemp[nPrbElm].compMethod = prbMapTemp[i].compMethod; +- prbMapTemp[nPrbElm].iqWidth = prbMapTemp[i].iqWidth; +- prbMapTemp[nPrbElm].ScaleFactor = prbMapTemp[i].ScaleFactor; +- prbMapTemp[nPrbElm].reMask = prbMapTemp[i].reMask; +- prbMapTemp[nPrbElm].BeamFormingType = prbMapTemp[i].BeamFormingType; +- +- nRBStart = prbMapTemp[i].nRBStart; +- nRBSize = prbMapTemp[i].nRBSize; ++ if (false) // Force it to generate multiple prbMapElm, one for each symbol even if they are of the same RBs ++ //if((nRBStart == prbMapTemp[i].nRBStart) && (nRBSize == prbMapTemp[i].nRBSize)) ++ { ++ prbMapTemp[nPrbElm].numSymb++; ++ } ++ else ++ { ++ nPrbElm++; ++ prbMapTemp[nPrbElm].nStartSymb = prbMapTemp[i].nStartSymb; ++ prbMapTemp[nPrbElm].nRBStart = prbMapTemp[i].nRBStart; ++ prbMapTemp[nPrbElm].nRBSize = prbMapTemp[i].nRBSize; ++ prbMapTemp[nPrbElm].nBeamIndex = prbMapTemp[i].nBeamIndex; ++ prbMapTemp[nPrbElm].bf_weight_update = prbMapTemp[i].bf_weight_update; ++ prbMapTemp[nPrbElm].compMethod = prbMapTemp[i].compMethod; ++ prbMapTemp[nPrbElm].iqWidth = prbMapTemp[i].iqWidth; ++ prbMapTemp[nPrbElm].ScaleFactor = prbMapTemp[i].ScaleFactor; ++ prbMapTemp[nPrbElm].reMask = prbMapTemp[i].reMask; ++ prbMapTemp[nPrbElm].BeamFormingType = prbMapTemp[i].BeamFormingType; ++ ++ nRBStart = prbMapTemp[i].nRBStart; ++ nRBSize = prbMapTemp[i].nRBSize; ++ } + } + } + diff --git a/fhi_lib/lib/src/xran_mem_mgr.c b/fhi_lib/lib/src/xran_mem_mgr.c index e1dcb6c..b3c3fae 100644 --- a/fhi_lib/lib/src/xran_mem_mgr.c @@ -1608,7 +1846,7 @@ index 7d4a5d0..b9b44ac 100644 #endif } diff --git a/fhi_lib/lib/src/xran_rx_proc.c b/fhi_lib/lib/src/xran_rx_proc.c -index e7056f4..0d3d8ac 100644 +index e7056f4..34b6d3b 100644 --- a/fhi_lib/lib/src/xran_rx_proc.c +++ b/fhi_lib/lib/src/xran_rx_proc.c @@ -35,7 +35,11 @@ @@ -1623,6 +1861,127 @@ index e7056f4..0d3d8ac 100644 #include #include +@@ -339,13 +343,33 @@ int32_t xran_process_srs_sym(void *arg, + pRbMap = (struct xran_prb_map *) p_xran_dev_ctx->sFHSrsRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers->pData; + if(pRbMap) + { +- prbMapElm = &pRbMap->prbMap[sect_id]; +- if(sect_id >= pRbMap->nPrbElm) ++ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13 ++ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13 ++ if(0 == p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable) { ++ section_id_tmp = prb_elem_id_tmp = sect_id; ++ } else { ++ /** Get the prb_elem_id */ ++ int8_t xran_port = xran_dev_ctx_get_port_id(p_xran_dev_ctx); ++ u_int8_t mixed_ul_sym_start = 0; ++ if (xran_fs_get_slot_type(xran_port, CC_ID, tti, XRAN_SLOT_TYPE_SP)) { ++ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID, tti); ++ } ++ ++ section_id_tmp = symb_id - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000 ++ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000 ++ //Note for future reference when using MTU 1500 ++ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ } ++ ++ prbMapElm = &pRbMap->prbMap[prb_elem_id_tmp /*sect_id*/]; ++ if(/*sect_id*/ prb_elem_id_tmp >= pRbMap->nPrbElm) + { +- print_err("sect_id %d !=pRbMap->nPrbElm %d\n", sect_id,pRbMap->nPrbElm); +- *mb_free = MBUF_FREE; +- return size; +- } ++ print_err("sect_id %d !=pRbMap->nPrbElm %d\n", sect_id,pRbMap->nPrbElm); ++ *mb_free = MBUF_FREE; ++ return size; ++ } + } + else + { +@@ -397,7 +421,25 @@ int32_t xran_process_srs_sym(void *arg, + else */ + { + struct xran_section_desc *p_sec_desc = NULL; +- prbMapElm = &pRbMap->prbMap[sect_id]; ++ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13 ++ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13 ++ if(0 == p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable) { ++ section_id_tmp = prb_elem_id_tmp = sect_id; ++ } else { ++ int8_t xran_port = xran_dev_ctx_get_port_id(p_xran_dev_ctx); ++ u_int8_t mixed_ul_sym_start = 0; ++ if (xran_fs_get_slot_type(xran_port, CC_ID, tti, XRAN_SLOT_TYPE_SP)) { ++ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID, tti); ++ } ++ u_int8_t section_id_tmp = symb_id - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000 ++ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000 ++ //Note for future reference when using MTU 1500 ++ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ } ++ ++ prbMapElm = &pRbMap->prbMap[prb_elem_id_tmp /*sect_id*/]; + // sec_desc_idx = 0;//prbMapElm->nSecDesc[symb_id]; + sec_desc_idx = prbMapElm->nSecDesc[symb_id]; + +@@ -537,14 +579,33 @@ int32_t xran_process_rx_sym(void *arg, + pos = (char*) p_xran_dev_ctx->sFrontHaulRxBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers[symb_id].pData; + pRbMap = (struct xran_prb_map *) p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[tti % XRAN_N_FE_BUF_LEN][CC_ID][Ant_ID].sBufferList.pBuffers->pData; + if(pRbMap){ +- /** Get the prb_elem_id */ ++ u_int8_t section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13 ++ u_int8_t prb_elem_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13 ++ if(0 == p_xran_dev_ctx->LiteOnIgnoreUPSectionIdEnable) { ++ section_id_tmp = prb_elem_id_tmp = sect_id; ++ } else { ++ /** Get the prb_elem_id */ ++ int8_t xran_port = xran_dev_ctx_get_port_id(p_xran_dev_ctx); ++ u_int8_t mixed_ul_sym_start = 0; ++ if (xran_fs_get_slot_type(xran_port, CC_ID, tti, XRAN_SLOT_TYPE_SP)) { ++ mixed_ul_sym_start = XRAN_NUM_OF_SYMBOL_PER_SLOT - xran_fs_get_num_ul_sym_sp(xran_port, CC_ID, tti); ++ } ++ ++ section_id_tmp = symb_id - mixed_ul_sym_start; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000 ++ prb_elem_id_tmp = section_id_tmp; // hack for LiteON FR2 : receive UP section ID = 13, MTU 9000 ++ //Note for future reference when using MTU 1500 ++ //prb_elem_id_tmp = 2*section_id_tmp; // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ //if (start_prbu !=0) // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ // prb_elem_id_tmp++; // For LiteON FR2 : receive UP section ID = 13, MTU 1500 ++ } ++ + total_sections=0; + if(pRbMap->prbMap[0].bf_weight.extType == 1) + { + for(i=0 ; i < pRbMap->nPrbElm ; i++) + { + total_sections += pRbMap->prbMap[i].bf_weight.numSetBFWs; +- if(total_sections >= (sect_id + 1)) ++ if(total_sections >= (/*sect_id*/ section_id_tmp + 1)) + { + prb_elem_id = i; + break; +@@ -553,7 +614,7 @@ int32_t xran_process_rx_sym(void *arg, + } + else + { +- prb_elem_id = sect_id; ++ prb_elem_id = prb_elem_id_tmp; /*sect_id*/; + } + + prbMapElm = &pRbMap->prbMap[prb_elem_id]; +@@ -597,7 +658,7 @@ int32_t xran_process_rx_sym(void *arg, + if(p_sec_desc){ + mb = p_sec_desc->pCtrl; + if(mb){ +- rte_pktmbuf_free(mb); ++ rte_pktmbuf_free(mb); + } + p_sec_desc->pData = iq_data_start; + p_sec_desc->pCtrl = mbuf; diff --git a/fhi_lib/lib/src/xran_timer.c b/fhi_lib/lib/src/xran_timer.c index 14a6a41..55182d8 100644 --- a/fhi_lib/lib/src/xran_timer.c diff --git a/cmake_targets/tools/setup_routes.sh b/cmake_targets/tools/setup_routes.sh deleted file mode 100755 index 67fe250be7..0000000000 --- a/cmake_targets/tools/setup_routes.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -for i in $(seq 1 $1); -do - let table=1000+$i - echo "sudo ip route add 10.0.1.0/24 dev oaitun_ue$i table $table" - sudo ip route add 10.0.1.0/24 dev oaitun_ue$i table $table - echo "sudo ip route add default via 10.0.1.1 dev oaitun_ue$i table $table" - sudo ip route add default via 10.0.1.1 dev oaitun_ue$i table $table - let octet=$i+1 - echo "sudo ip rule add from 10.0.1.$octet table $table" - sudo ip rule add from 10.0.1.$octet table $table -done diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index c3f3d5ae21..f8b10ad14b 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -213,7 +213,7 @@ int config_check_unknown_cmdlineopt(configmodule_interface_t *cfg, char *prefix) return unknowndetected; } /* config_check_unknown_cmdlineopt */ -int config_process_cmdline(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix) +int config_process_cmdline(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, const char *prefix) { int c = cfg->argc; int i,j; diff --git a/common/config/config_common.c b/common/config/config_common.c index c617c426d7..0b4b8f76d6 100644 --- a/common/config/config_common.c +++ b/common/config/config_common.c @@ -118,7 +118,7 @@ void *config_allocate_new(configmodule_interface_t *cfg, int sz, bool autoFree) return ptr; } -int config_setdefault_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix) +int config_setdefault_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix) { int status = 0; config_check_valptr(cfg, cfgoptions, sizeof(*cfgoptions->iptr), 1); @@ -132,7 +132,7 @@ int config_setdefault_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, return status; } -int config_setdefault_int64(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix) +int config_setdefault_int64(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix) { int status = 0; config_check_valptr(cfg, cfgoptions, sizeof(*cfgoptions->i64ptr), 1); @@ -150,7 +150,7 @@ int config_setdefault_int64(configmodule_interface_t *cfg, paramdef_t *cfgoption return status; } -int config_setdefault_intlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix) +int config_setdefault_intlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix) { int status = 0; @@ -167,7 +167,7 @@ int config_setdefault_intlist(configmodule_interface_t *cfg, paramdef_t *cfgopti return status; } -int config_setdefault_string(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix) +int config_setdefault_string(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix) { int status = 0; @@ -190,7 +190,7 @@ int config_setdefault_string(configmodule_interface_t *cfg, paramdef_t *cfgoptio return status; } -int config_setdefault_stringlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix) +int config_setdefault_stringlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix) { int status = 0; @@ -210,7 +210,7 @@ int config_setdefault_stringlist(configmodule_interface_t *cfg, paramdef_t *cfgo return status; } -int config_setdefault_double(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix) +int config_setdefault_double(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix) { int status = 0; config_check_valptr(cfg, cfgoptions, sizeof(*cfgoptions->dblptr), 1); @@ -224,7 +224,7 @@ int config_setdefault_double(configmodule_interface_t *cfg, paramdef_t *cfgoptio return status; } -int config_assign_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *ipv4addr) +int config_assign_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *ipv4addr) { config_check_valptr(cfg, cfgoptions, sizeof(*cfgoptions->uptr), 1); int rst=inet_pton(AF_INET, ipv4addr,cfgoptions->uptr ); @@ -246,7 +246,7 @@ int config_assign_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions return 0; } -int config_setdefault_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix) +int config_setdefault_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix) { int status = 0; @@ -322,7 +322,7 @@ void config_assign_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, ch * @param[in] prefix Optional prefix for the parameter name (can be NULL). * @return 1 if the default value was set, 0 if ignored, or -1 on error/unsupported type. */ -int config_common_getdefault(configmodule_interface_t *cfg, paramdef_t *cfgoption, char *prefix) +int config_common_getdefault(configmodule_interface_t *cfg, paramdef_t *cfgoption, const char *prefix) { if( (cfgoption->paramflags & PARAMFLAG_DONOTREAD) != 0) { return 0; diff --git a/common/config/config_common.h b/common/config/config_common.h index 00211c9519..0400e703c7 100644 --- a/common/config/config_common.h +++ b/common/config/config_common.h @@ -41,16 +41,16 @@ extern "C" #endif void config_check_valptr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int elt_sz, int nb_elt); /* functions to set a parameter to its default value */ -int config_setdefault_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix); -int config_setdefault_int64(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix); -int config_setdefault_intlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix); -int config_setdefault_string(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix); -int config_setdefault_stringlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix); -int config_setdefault_double(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix); -int config_setdefault_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix); +int config_setdefault_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix); +int config_setdefault_int64(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix); +int config_setdefault_intlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix); +int config_setdefault_string(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix); +int config_setdefault_stringlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix); +int config_setdefault_double(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix); +int config_setdefault_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix); void *config_allocate_new(configmodule_interface_t *cfg, int sz, bool autoFree); void config_assign_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *fullname, int val); -int config_common_getdefault(configmodule_interface_t *cfg, paramdef_t *cfgoption, char *prefix); +int config_common_getdefault(configmodule_interface_t *cfg, paramdef_t *cfgoption, const char *prefix); #ifdef __cplusplus } diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index f5dfe6137f..5d8bb2cfcc 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -150,7 +150,7 @@ int config_cmdlineonly_getlist(configmodule_interface_t *cfg, return 0; } -int config_cmdlineonly_get(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix) +int config_cmdlineonly_get(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, const char *prefix) { int defval; int fatalerror=0; diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index d5f87d0f8b..2c45f788d4 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -59,10 +59,10 @@ #define CONFIG_ABORT (1<<21) // config failed,abort execution #define CONFIG_NOOOPT (1<<22) // no -O option found when parsing command line struct configmodule_interface; -typedef int (*configmodule_getfunc_t)(struct configmodule_interface *, paramdef_t *, int numparams, char *prefix); +typedef int (*configmodule_getfunc_t)(struct configmodule_interface *, paramdef_t *, int numparams, const char *prefix); typedef int ( *configmodule_getlistfunc_t)(struct configmodule_interface *, paramlist_def_t *, paramdef_t *, int numparams, char *prefix); -typedef int (*configmodule_setfunc_t)(paramdef_t *cfgoptions, int numoptions, char *prefix); +typedef int (*configmodule_setfunc_t)(paramdef_t *cfgoptions, int numoptions, const char *prefix); typedef void (*configmodule_endfunc_t)(struct configmodule_interface *cfg); typedef int (*configmodule_initfunc_t)(struct configmodule_interface *cfg); diff --git a/common/config/config_paramdesc.h b/common/config/config_paramdesc.h index 8ddd507ee6..9333a778af 100644 --- a/common/config/config_paramdesc.h +++ b/common/config/config_paramdesc.h @@ -105,7 +105,7 @@ typedef union checkedparam { #define DEFAULT_EXTRA_SZ 256 typedef struct paramdef { char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */ - char *helpstr; /* help string */ + const char *helpstr; /* help string */ unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */ union { /* pointer to the parameter value, completed by the config module */ char **strptr; @@ -122,7 +122,7 @@ typedef struct paramdef { void *voidptr; } ; union { /* default parameter value, to be used when PARAMFLAG_MANDATORY is not specified */ - char *defstrval; + const char *defstrval; char **defstrlistval; uint32_t defuintval; int defintval; @@ -161,6 +161,50 @@ typedef struct paramdef { #define TYPE_LIST 55 #define ANY_IPV4ADDR_STRING "0.0.0.0" + +// Macros to simplify defining parameters in paramdef_t arrays in C++ source code +#define OPTNAME(x) .optname = x +#define HELPSTR(x) .helpstr = x +#define PARAMFLAG(x) .paramflags = x +#define PARAMTYPE(x) .type = x +#define STRINGPARAM(name, help, flags, ptr, defval) \ + { \ + OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .strptr = ptr, .defstrval = defval, PARAMTYPE(TYPE_STRING), .numelt = 0 \ + } +#define DOUBLEPARAM(name, help, flags, ptr, defval) \ + { \ + OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .dblptr = ptr, .defdblval = defval, PARAMTYPE(TYPE_DOUBLE), .numelt = 0 \ + } +#define INTPARAM(name, help, flags, ptr, defval) \ + { \ + OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .iptr = ptr, .defintval = defval, PARAMTYPE(TYPE_INT), .numelt = 0 \ + } +#define UINT16PARAM(name, help, flags, ptr, defval) \ + { \ + OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .u16ptr = ptr, .defuintval = defval, PARAMTYPE(TYPE_UINT16), .numelt = 0 \ + } +#define STRLISTPARAM(name, help, flags, ptr, defval) \ + { \ + OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .strlistptr = ptr, .defstrlistval = defval, PARAMTYPE(TYPE_STRINGLIST), \ + .numelt = 0 \ + } +#define INT64PARAM(name, help, flags, ptr, defval) \ + { \ + OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .i64ptr = ptr, .defint64val = defval, PARAMTYPE(TYPE_INT64), .numelt = 0 \ + } +#define INTPARAM(name, help, flags, ptr, defval) \ + { \ + OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .iptr = ptr, .defintval = defval, PARAMTYPE(TYPE_INT), .numelt = 0 \ + } +#define BOOLPARAM(name, help, flags, ptr, defval) \ + { \ + OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .iptr = ptr, .defintval = defval, PARAMTYPE(TYPE_INT), .numelt = 0 \ + } +#define UINT64PARAM(name, help, flags, ptr, defval) \ + { \ + OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .u64ptr = ptr, .defuintval = defval, PARAMTYPE(TYPE_UINT64), .numelt = 0 \ + } + typedef struct paramlist_def { char listname[MAX_OPTNAME_SIZE]; paramdef_t **paramarray; diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 9f7477f5cd..7c92a611de 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -71,7 +71,7 @@ int config_get_processedint(configmodule_interface_t *cfg, paramdef_t *cfgoption return ret; } -void config_printhelp(paramdef_t *params,int numparams, char *prefix) { +void config_printhelp(paramdef_t *params,int numparams, const char *prefix) { printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix,numparams); for (int i=0 ; i= 0 && idx < num, "Invalid parameter name %s\n", name); + return &pd[idx]; +} diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index 13bf62dd1b..3aeeeec3c1 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -49,17 +49,19 @@ extern configmodule_interface_t *uniqCfg; #define CONFIG_SETRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags |= P; } #define CONFIG_CLEARRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags &= (~P); } #define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F)) -int config_paramidx_fromname(paramdef_t *params, int numparams, char *name); +#define gpd(pd_array, nump, name) config_get_paramdef_from_name(pd_array, nump, name) + +int config_paramidx_fromname(const paramdef_t *params, int numparams, const char *name); /* utility functions, to be used by configuration module and/or configuration libraries */ -void config_printhelp(paramdef_t *, int numparams, char *prefix); -int config_process_cmdline(configmodule_interface_t *cfg, paramdef_t *params, int numparams, char *prefix); -int config_assign_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *ipv4addr); +void config_printhelp(paramdef_t *, int numparams, const char *prefix); +int config_process_cmdline(configmodule_interface_t *cfg, paramdef_t *params, int numparams, const char *prefix); +int config_assign_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *ipv4addr); /* apis to get/check parameters, to be used by oai modules, at configuration time */ #define CONFIG_CHECKALLSECTIONS "ALLSECTIONS" int config_check_unknown_cmdlineopt(configmodule_interface_t *cfg, char *prefix); -int config_get(configmodule_interface_t *cfg, paramdef_t *params, int numparams, char *prefix); +int config_get(configmodule_interface_t *cfg, paramdef_t *params, int numparams, const char *prefix); int config_getlist(configmodule_interface_t *cfg, paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix); /* apis to set some of the paramdef_t fields before using the get/getlist api's */ @@ -75,6 +77,7 @@ int config_check_modify_integer(configmodule_interface_t *cfg, paramdef_t *param int config_check_intrange(configmodule_interface_t *cfg, paramdef_t *param); int config_check_strval(configmodule_interface_t *cfg, paramdef_t *param); int config_checkstr_assign_integer(configmodule_interface_t *cfg, paramdef_t *param); +const paramdef_t *config_get_paramdef_from_name(const paramdef_t *pd, int num, const char *name); #define CONFIG_GETCONFFILE (config_get_if()->cfgP[0]) diff --git a/common/config/yaml/tests/test_yaml_config.cpp b/common/config/yaml/tests/test_yaml_config.cpp index 814e3a3635..b2bd53e349 100644 --- a/common/config/yaml/tests/test_yaml_config.cpp +++ b/common/config/yaml/tests/test_yaml_config.cpp @@ -411,7 +411,7 @@ TEST(yaml_config, test_read_ipv4) { config_yaml_get(cfg, &p, 1, prefix); printf("%x\n", addr); - p.defstrval = strdup("10.0.0.1"); + p.defstrval = "10.0.0.1"; strncpy(p.optname, "ipv4_3", sizeof(p.optname) - 1); config_yaml_get(cfg, &p, 1, prefix); printf("%x\n", addr); @@ -419,7 +419,6 @@ TEST(yaml_config, test_read_ipv4) { config_yaml_end(cfg); free(cfg->cfgP[0]); end_configmodule(cfg); - free(p.defstrval); } TEST(yaml_config, yaml_read_str_as_int) { diff --git a/common/platform_constants.h b/common/platform_constants.h index 4cfd83a369..68afd25810 100644 --- a/common/platform_constants.h +++ b/common/platform_constants.h @@ -100,4 +100,5 @@ // SDAP #define MAX_QOS_FLOWS 64 +#define SPEED_OF_LIGHT 299792458 // in m/s #endif /* __PLATFORM_CONSTANTS_H__ */ diff --git a/common/utils/CMakeLists.txt b/common/utils/CMakeLists.txt index c3c7720628..dc997db6c7 100644 --- a/common/utils/CMakeLists.txt +++ b/common/utils/CMakeLists.txt @@ -23,3 +23,6 @@ endif() add_subdirectory(barrier) add_subdirectory(actor) add_subdirectory(shm_iq_channel) +if (ENABLE_TESTS) + add_subdirectory(tests) +endif() diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index cd81deda2b..d2405f9033 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -138,11 +138,11 @@ ID = GNB_PHY_UL_PAYLOAD_RX_BITS ID = GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE DESC = gNodeB channel estimation in the frequency domain GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB - FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : buffer,chest_t + FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : int,port : buffer,chest_f ID = GNB_PHY_UL_TIME_CHANNEL_ESTIMATE DESC = gNodeB channel estimation in the time domain GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB - FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : buffer,chest_t + FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : int,port : buffer,chest_t ID = GNB_PHY_UL_SNR_ESTIMATE DESC = gNodeB SNR estimation based on SRS GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB @@ -155,6 +155,10 @@ ID = GNB_PHY_DL_OUTPUT_SIGNAL DESC = gNodeB output data in the freq domain for slots GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB FORMAT = int,gNB_ID : int,frame : int,slot : int,antenna : buffer,txdata +ID = GNB_PHY_UL_SRS_TOA_NS + DESC = gNB ToA estimate from SRS (in ns) + GROUP = ALL:PHY:GNB + FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : buffer,toa_ns #MAC logs ID = ENB_MAC_UE_DL_SDU diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index 825012ce6a..13eec39776 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -252,7 +252,7 @@ load_module_shlib_exit: return ret; } -void * get_shlibmodule_fptr(char *modname, char *fname) +void * get_shlibmodule_fptr(const char *modname, const char *fname) { for (int i=0; i #include "assertions.h" #include "common/utils/utils.h" +#include "common/utils/LOG/log.h" #define MAX_SI_GROUPS 3 #define NR_MAX_PDSCH_TBS 3824 @@ -272,6 +273,19 @@ static __attribute__((always_inline)) inline int count_bits64_with_mask(uint64_t return count_bits64(v & mask); } +static inline void warn_higher_threequarter_fs(const int n_rb, const int mu) +{ + LOG_W(PHY, + "3/4 sampling is not possible for current PRB size: %d and numerology: %d.\n " + "So 6/4 sampling is chosen to support x3xx type USRPs.\n " + "Note that this sampling rate increases fronthaul traffic, FFT buffer size and processing time by a factor of two compared " + "to 3/4 sampling rate.\n " + "Some PRACH configuration might not be supported with 6/4 FFT size.\n " + "Consider reducing the PRB size that would fit within the FFT size of 3/4 sampling\n", + n_rb, + mu); +} + uint64_t reverse_bits(uint64_t in, int n_bits); void reverse_bits_u8(uint8_t const* in, size_t sz, uint8_t* out); @@ -346,6 +360,7 @@ float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2); #define CEILIDIV(a,b) ((a+b-1)/b) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) +#define BOUNDED_EVAL(a, b, c) (min(c, max(a, b))) static const char *const duplex_mode_txt[] = {"FDD", "TDD"}; diff --git a/common/utils/system.c b/common/utils/system.c index 270c3ae321..e38d97768a 100644 --- a/common/utils/system.c +++ b/common/utils/system.c @@ -282,8 +282,13 @@ void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, ret=pthread_create(t, &attr, func, param); AssertFatal(ret == 0, "Error in pthread_create(): ret: %d, errno: %d\n", ret, errno); - - pthread_setname_np(*t, name); + + char short_name[16]; + strncpy(short_name, name, sizeof(short_name) - 1); + short_name[sizeof(short_name) - 1] = '\0'; + ret = pthread_setname_np(*t, short_name); + AssertFatal(ret == 0, "Error in pthread_setname_np(): ret: %d, errno: %d\n", ret, errno); + if (affinity != -1 ) { cpu_set_t cpuset; CPU_ZERO(&cpuset); diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h index 6c1c20125e..82f2eba3ec 100644 --- a/common/utils/telnetsrv/telnetsrv.h +++ b/common/utils/telnetsrv/telnetsrv.h @@ -76,7 +76,7 @@ typedef struct webdatadef { typedef void(*telnet_printfunc_t)(const char* format, ...); typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt); typedef int (*webfunc_t)(char *cmdbuff, int debug, telnet_printfunc_t prnt, ...); -typedef int (*webfunc_getdata_t)(char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt); +typedef int (*webfunc_getdata_t)(const char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt); typedef int(*qcmdfunc_t)(char*, int, telnet_printfunc_t prnt,void *arg); #define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1 << 0) // ask the telnet server to push the command in a thread pool queue @@ -195,7 +195,7 @@ VT escape sequence definition, for smarter display.... #define TELNET_ADDCMD_FNAME "add_telnetcmd" #define TELNET_POLLCMDQ_FNAME "poll_telnetcmdq" #define TELNET_PUSHCMD_FNAME "telnet_pushcmd" -typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *); +typedef int(*add_telnetcmd_func_t)(const char *, telnetshell_vardef_t *, telnetshell_cmddef_t *); typedef void(*poll_telnetcmdq_func_t)(void *qid,void *arg); typedef void (*push_telnetcmd_func_t)(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt); #ifdef TELNETSERVERCODE diff --git a/common/utils/telnetsrv/telnetsrv_5Gue_measurements.c b/common/utils/telnetsrv/telnetsrv_5Gue_measurements.c index 6f2d1c7516..323a4175bc 100644 --- a/common/utils/telnetsrv/telnetsrv_5Gue_measurements.c +++ b/common/utils/telnetsrv/telnetsrv_5Gue_measurements.c @@ -50,7 +50,9 @@ #include "telnetsrv_ltemeasur_def.h" #include "telnetsrv_cpumeasur_def.h" #include "openair2/LAYER2/NR_MAC_UE/mac_defs.h" -#include "openair1/PHY/phy_extern_nr_ue.h" +#include "openair1/PHY/defs_nr_UE.h" + +extern PHY_VARS_NR_UE ***PHY_vars_UE_g; void measurcmd_display_macstats(telnet_printfunc_t prnt); void measurcmd_display_macstats_ue(telnet_printfunc_t prnt); diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 8b00d529c5..10f9626ef0 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -38,6 +38,7 @@ #include "openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_config.h" #include "openair2/RRC/NR/rrc_gNB_mobility.h" #include "openair3/NGAP/ngap_gNB_ue_context.h" @@ -276,6 +277,8 @@ static int get_current_bwp(char *buf, int debug, telnet_printfunc_t prnt) if (rnti < 0) ERROR_MSG_RET("could not identify UE (no UE, no such RNTI, or multiple UEs)\n"); NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti); + if (!UE) + ERROR_MSG_RET("could not find UE with RNTI %04x\n", rnti); int dl_bwp = UE->current_DL_BWP.bwp_id; const char *dl_bwp_text = dl_bwp > 0 ? "dedicated" : "initial"; int ul_bwp = UE->current_UL_BWP.bwp_id; @@ -348,7 +351,7 @@ static int trigger_ngap_pdu_session_release(char *buf, int debug, telnet_printfu if (sid < 1 || sid > 255) { ERROR_MSG_RET("Invalid pdusession_id(int): %s (must be between 1 and 255)\n", tokens[i]); } - msg->pdusession_release_params[nb_sessions++].pdusession_id = sid; + msg->pdusession_ids[nb_sessions++] = sid; } msg->nb_pdusessions_torelease = nb_sessions; @@ -356,7 +359,7 @@ static int trigger_ngap_pdu_session_release(char *buf, int debug, telnet_printfu if (prnt) { prnt("Triggering NGAP PDU Session Release for gNB_ue_ngap_id=%d: releasing pdusession_id=%d", gNB_ue_ngap_id); for (int i = 0; i < nb_sessions; ++i) { - prnt(" %d,", msg->pdusession_release_params[i].pdusession_id); + prnt(" %d,", msg->pdusession_ids[i]); } prnt("\n"); } @@ -365,6 +368,24 @@ static int trigger_ngap_pdu_session_release(char *buf, int debug, telnet_printfu return 0; } +static int trigger_bwp_switch(char *buf, int debug, telnet_printfunc_t prnt) +{ + char *sbwpId = strtok(buf, " "); + int bwpId = atoi(sbwpId); + char *srnti = strtok(NULL, " "); + prnt("bwpId %d rnti %s\n", bwpId, srnti); + int rnti = fetch_rnti(srnti, prnt); + if (rnti < 0) + ERROR_MSG_RET("could not identify UE (no UE, no such RNTI, or multiple UEs)\n"); + if (!nr_trigger_bwp_switch(rnti, bwpId)) { + prnt("failed trigger BWP switch for UE %04x BWP ID %d\n", rnti, bwpId); + return -1; + } else { + prnt("triggered BWP switch to BWP ID %d for UE %04x\n", bwpId, rnti); + return 0; + } +} + static telnetshell_cmddef_t cicmds[] = { {"get_single_rnti", "", get_single_rnti}, {"force_reestab", "[rnti(hex,opt)]", trigger_reestab}, @@ -374,6 +395,7 @@ static telnetshell_cmddef_t cicmds[] = { {"trigger_f1_ho", "[rrc_ue_id(int,opt)]", rrc_gNB_trigger_f1_ho}, {"fetch_du_by_ue_id", "[rrc_ue_id(int,opt)]", fetch_du_by_ue_id}, {"get_current_bwp", "[rnti(hex,opt)]", get_current_bwp}, + {"trigger_bwp_switch", "newBWPId [rnti(hex,opt)]", trigger_bwp_switch}, {"trigger_n2_ho", "[neighbour_pci(uint32_t),ueId(uint32_t)]", rrc_gNB_trigger_n2_ho}, {"pdu_session_release", "[gNB_ue_ngap_id(int,opt)]", trigger_ngap_pdu_session_release}, {"", "", NULL}, diff --git a/common/utils/telnetsrv/telnetsrv_ciUE.c b/common/utils/telnetsrv/telnetsrv_ciUE.c index 6f86f1678f..cc580b1a83 100644 --- a/common/utils/telnetsrv/telnetsrv_ciUE.c +++ b/common/utils/telnetsrv/telnetsrv_ciUE.c @@ -37,8 +37,8 @@ #include "openair2/LAYER2/NR_MAC_UE/mac_defs.h" #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" #include "openair2/RRC/NR_UE/rrc_proto.h" -#include "openair1/PHY/phy_extern_nr_ue.h" #include "openair1/PHY/defs_nr_common.h" +#include "openair1/PHY/defs_nr_UE.h" #include "openair3/NAS/NR_UE/nr_nas_msg.h" #define TELNETSERVERCODE @@ -46,6 +46,8 @@ #define ERROR_MSG_RET(mSG, aRGS...) do { prnt(mSG, ##aRGS); return 1; } while (0) +extern PHY_VARS_NR_UE ***PHY_vars_UE_g; + /* UE L2 state string */ const char* NR_UE_L2_STATE_STR[] = { #define UE_STATE(state) #state, diff --git a/common/utils/tests/CMakeLists.txt b/common/utils/tests/CMakeLists.txt new file mode 100644 index 0000000000..de855b5944 --- /dev/null +++ b/common/utils/tests/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(test_tpool_vs_actors test_tpool_vs_actors.c) +target_link_libraries(test_tpool_vs_actors PRIVATE thread-pool pthread LOG minimal_lib actor) diff --git a/common/utils/tests/test_tpool_vs_actors.c b/common/utils/tests/test_tpool_vs_actors.c new file mode 100644 index 0000000000..97f2867f42 --- /dev/null +++ b/common/utils/tests/test_tpool_vs_actors.c @@ -0,0 +1,126 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "actor.h" +#include "thread-pool.h" +#include "task.h" +#include "log.h" +#include + +#define NUM_THREADS 10 +#define NUM_JOBS 200000 + +typedef struct { + struct timespec ts; + int actor_index; +} actor_task_t; + +long long delay_table[NUM_THREADS] = {0}; + +void calculate_delay(struct timespec* send_ts, int thread_index) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + long long recv_time = ts.tv_sec * 1000000000LL + ts.tv_nsec; + long long send_time = send_ts->tv_sec * 1000000000LL + send_ts->tv_nsec; + long long delay = recv_time - send_time; + delay_table[thread_index] += delay; +} + +void tpool_function(void* args) +{ + int worker_id = get_tpool_worker_index(); + calculate_delay((struct timespec*)args, worker_id); + free(args); +} + +void actor_function(void* args) +{ + actor_task_t* actor_args = (actor_task_t*)args; + calculate_delay(&actor_args->ts, actor_args->actor_index); +} + +int main() +{ + logInit(); + tpool_t pool; + char params[NUM_THREADS * 4]; + memset(params, 0, sizeof(params)); + for (int i = 0; i < NUM_THREADS; i++) { + char buf[4]; + snprintf(buf, sizeof(buf), "%d,", -1); + strcat(params, buf); + } + + initTpool(params, &pool, true); + + // Example task + task_t task; + task.func = tpool_function; + task.args = NULL; + + // Push tasks to the thread pool + for (int i = 0; i < NUM_JOBS; i++) { + struct timespec* ts = malloc(sizeof(struct timespec)); + clock_gettime(CLOCK_MONOTONIC, ts); + task.args = ts; + pushTpool(&pool, task); + } + + // Abort the thread pool + abortTpool(&pool); + + long long sum_delay = 0; + for (int i = 0; i < NUM_THREADS; i++) { + sum_delay += delay_table[i]; + } + float average_delay = sum_delay / (NUM_JOBS * 1.0f); + printf("Average task delay on tpool: %.2f ns\n", average_delay); + + + memset(delay_table, 0, sizeof(delay_table)); + + Actor_t actors[NUM_THREADS]; + for (int i = 0; i < NUM_THREADS; i++) { + init_actor(&actors[i], "example_actor", -1); + } + + // Push tasks to the actors + for (int i = 0; i < NUM_JOBS; i++) { + notifiedFIFO_elt_t* task = newNotifiedFIFO_elt(sizeof(actor_task_t), 0, NULL, actor_function); + actor_task_t* arg_ts = (actor_task_t*)NotifiedFifoData(task); + arg_ts->actor_index = i % NUM_THREADS; + clock_gettime(CLOCK_MONOTONIC, &arg_ts->ts); + pushNotifiedFIFO(&actors[i % NUM_THREADS].fifo, task); + } + + for (int i = 0; i < NUM_THREADS; i++) { + shutdown_actor(&actors[i]); + } + + sum_delay = 0; + for (int i = 0; i < NUM_THREADS; i++) { + sum_delay += delay_table[i]; + } + average_delay = sum_delay / (NUM_JOBS * 1.0f); + printf("Average task delay on actors: %.2f ns\n", average_delay); + return 0; +} \ No newline at end of file diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c index 2a31602e6e..2983c779a7 100644 --- a/common/utils/threadPool/thread-pool.c +++ b/common/utils/threadPool/thread-pool.c @@ -55,12 +55,47 @@ void pushTpool(tpool_t* tpool, task_t task) push_not_q(&q_arr[index % len_thr], task); } +// Same as above, but avoid certain tpool workers based on the mask +void pushTpool_mask(tpool_t* tpool, task_t task, uint64_t mask) +{ + DevAssert(tpool != NULL); + if (tpool->len_thr == 0) { + task.func(task.args); + return; + } + + size_t index = tpool->index++; + size_t const len_thr = tpool->len_thr; + + not_q_t* q_arr = (not_q_t*)tpool->q_arr; + + for (size_t i = 0; i < len_thr; ++i) { + int index = (i + tpool->index) % len_thr; + if ((1UL << index) & mask) + continue; + if (try_push_not_q(&q_arr[index], task)) { + return; + } + } + + while ((1ULL << (index % len_thr)) & mask) + index++; + push_not_q(&q_arr[index % len_thr], task); +} + +__thread int tpool_worker_index = -1; +int get_tpool_worker_index(void) +{ + return tpool_worker_index; +} + static void* worker_thread(void* arg) { DevAssert(arg != NULL); task_thread_args_t* args = (task_thread_args_t*)arg; int const idx = args->idx; + tpool_worker_index = idx; tpool_t* tpool = args->tpool; uint32_t const len = tpool->len_thr; @@ -87,7 +122,10 @@ static void* worker_thread(void* arg) } if (ret.t.func == NULL && ret.t.args == NULL) { - pushTpool(tpool, (task_t){.args = NULL, .func = NULL}); + tpool->dead_mask |= 1ULL << idx; + if (__builtin_popcountll(tpool->dead_mask) == tpool->len_thr) + break; + pushTpool_mask(tpool, (task_t){.args = NULL, .func = NULL}, tpool->dead_mask); break; } ret.t.func(ret.t.args); diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index 8e5d329499..75fc1487bb 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -50,6 +50,7 @@ typedef struct { void* q_arr; pthread_barrier_t barrier; + _Atomic(uint64_t) dead_mask; } tpool_t; /// @brief Push job to threadpool. May run task inline in case there are no worker threads @@ -82,4 +83,8 @@ void initFloatingCoresTpool(int nbThreads,tpool_t *pool, bool performanceMeas, c /// Convenience macro #define initTpool(PARAMPTR,TPOOLPTR, MEASURFLAG) initNamedTpool(PARAMPTR,TPOOLPTR, MEASURFLAG, NULL) + +/// Returns the index of the worker thread in the thread pool +/// @return index of the worker thread in a thread pool or -1 if not called from a thread pool worker thread +int get_tpool_worker_index(void); #endif diff --git a/common/utils/utils.h b/common/utils/utils.h index df188b812f..ede5cf7a84 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -33,8 +33,8 @@ extern "C" { __typeof__ (b) _b = (b); \ _a < _b ? _a : _b; }) - - +#define IS_BIT_SET(a, b) ((a >> b) & 1) +#define SET_BIT(a, b) (a | (1 << b)) #ifdef __cplusplus #ifdef min diff --git a/doc/Aerial_FAPI_Split_Tutorial.md b/doc/Aerial_FAPI_Split_Tutorial.md index 6eef02dc34..23ce37312d 100644 --- a/doc/Aerial_FAPI_Split_Tutorial.md +++ b/doc/Aerial_FAPI_Split_Tutorial.md @@ -82,7 +82,7 @@ of the FAPI 10.04 version of the SRS PDU, and RX_Beamforming PDU. | Applicative Threads | Allocated CPUs | |------------------------|----------------| | PTP & PHC2SYS Services | 41 | -| OAI `nr-softmodem` | 13-14 | +| OAI `nr-softmodem` | 13-16 | ## PTP configuration diff --git a/doc/BUILD.md b/doc/BUILD.md index 8298204859..bf05a5cc00 100644 --- a/doc/BUILD.md +++ b/doc/BUILD.md @@ -32,7 +32,7 @@ The main oai binaries, which are tested by the Continuous Integration process ar - The 5G gNodeB: `nr-softmodem` - The 5G CU-UP: `nr-cuup` - The LTE PHY simulators: `dlsim` and `ulsim` -- The 5G PHY simulators: `nr_dlschsim`, `nr_dlsim`, `nr_pbchsim`, `nr_pucchsim`, `nr_ulschsim`, `nr_ulsim`, `polartest`, `smallblocktest`, `nr _ulsim`, `ldpctest` +- The 5G PHY simulators: `nr_dlschsim`, `nr_dlsim`, `nr_pbchsim`, `nr_pucchsim`, `nr_ulschsim`, `nr_ulsim`, `polartest`, `smallblocktest`, `nr _ulsim`, `ldpctest`, `nr_srssim` Running the [build_oai](../cmake_targets/build_oai) script also generates some utilities required to build and/or run the oai softmodem binaries: diff --git a/doc/Doxyfile b/doc/Doxyfile index 85cb5776c0..39c7983e72 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1924,7 +1924,6 @@ INPUT = \ @CMAKE_CURRENT_SOURCE_DIR@/../openair2/SDAP/nr_sdap/nr_sdap_entity.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/defs_gNB.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/impl_defs_top.h \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/phy_extern_nr_ue.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/INIT/lte_parms.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/INIT/nr_init_ru.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/INIT/nr_parms.c \ diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index c703899c16..34a3f17987 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -352,8 +352,11 @@ These modes of operation are supported: - Formats 0,1,2,3, A1-A3, B1-B3 * NTN - TA adjustemt based on ntn-Config-r17 information - - Autonomous TA adjustemt between SIB19 receptions based on DL time tracking - - UL Doppler pre-compensation based on continuous DL FO estimation + - Different TA adjustemt algorithms between SIB19 receptions: + - Autonomous TA adjustemt based on DL time tracking + - Standard compliant epoch time based TA adjustment including orbital propagation + - DL Doppler compensation based on ntn-Config-r17 information + - UL Doppler pre-compensation based on ntn-Config-r17 information and residual DL FO estimation * Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported) * Highly efficient 3GPP compliant polar encoder and decoder * Encoder and decoder for short block diff --git a/doc/MAC/mac-usage.md b/doc/MAC/mac-usage.md index a3b174f50c..1ce15ec9d6 100644 --- a/doc/MAC/mac-usage.md +++ b/doc/MAC/mac-usage.md @@ -255,8 +255,6 @@ configuration](../RRC/rrc-usage.md) as well for SIB configuration. * `pusch_AntennaPorts` (default 1): number of antenna ports in PUSCH * `maxMIMO_layers` (default -1=unlimited): maximum number of MIMO layers to use in downlink -* `sib1_tda` (default 1): time domain allocation (TDA) indices to use for SIB1 - (38.214 section 5.1.2.1.1) * `do_CSIRS` (default 0): flag whether to use channel-state information reference signal (CSI-RS) * `do_SRS` (default 0): flag whether to use sounding reference signal (SRS) @@ -420,3 +418,29 @@ Note that you should increase the aggregation level candidates as described in [the corresponding section above](#pdcch-aggregation-level). This is because the scheduler has to schedule multiple DCIs in a single DL slots for multiple UL slots. As a suggestion, you could try `uess_agg_levels = [4, 2, 2, 0, 0]`. + +## Multiple Dedicated BWPs + +A maximum of 4 dedicated BWPs can be configured for a UE per standard, but only +1 BWP can be active in UL and DL direction at a given time. In the code we +only configure a single BWP for the UE at a given time and we would switch by +reconfiguring this BWP. All this procedure is transparent for users and LOGs +mark BWP switching according to the configuration file enumeration. It is +possible to configure multiple dedicated BWPs and 1st active BWP via +configuration file. + +### Setup of the Configuration files ## + +In the configuration file you have the option to select the 1st active BWP, the +BWP location and SCS of each BWP in the following way (example with 2 +additional BWPs): + +``` + first_active_bwp = 1; + bwp_list = ({ scs = 1; bwpStart = 0; bwpSize = 106;}, + { scs = 1; bwpStart = 0; bwpSize = 24;}); +``` + +This example configures 3 additional BWPs, with IDs from 1 to 3. A similar +example can be found in configuration file +`ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf` tested in CI. diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index 5f95921a64..1796e4865f 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -1123,24 +1123,32 @@ The assumed configuration is that with N RUs each having an M×M configuration, we effectively reach an (N×M)×(N×M) configuration. Some caveats: -- Since it's a distributed antenna, this implies that this setup will deploy a +- Even in case of a distributed antenna, this setup will deploy a single cell only -- multiple cells on different RUs are not supported. - All RUs should use the same MTU, so either "normal" (1500 byte) MTU or jumbo frames, but not a mix of both. - We tested only two RUs as of now, i.e., an 8×8 configuration. -- Testing is currently limited to 4 logical antenna ports in DL; in UL, up to 8 can be used. +- In case of a single array is currently limited to 4 logical antenna ports in DL; + in UL, up to 8 can be used. -For two RUs each using a 4x4 configuration, make sure to configure the 8x8 -configuration, i.e., set `nb_tx` and `nb_rx` under `RUs` to 8 each (NOT two -`RUs`!). Also, set the antenna port information as listed above, i.e., +For two RUs using a 8x8 configuration, i.e. a single antenna system, the reference DU configuration file is +[`gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650.conf). -``` -pdsch_AntennaPorts_XP = 2; -pdsch_AntennaPorts_N1 = 2; -pusch_AntennaPorts = 8; -maxMIMO_layers = 2; -``` -Once testing for 8 antenna ports in DL is complete, we will change pdsch_AntennaPorts_N1 to 4. +For two RUs each using a 4x4 configuration, i.e. a distributed antenna system (DAS), +we use the analog beamforming implementation. More details can be found in +[this document](./analog_beamforming.md). It is important to note that +the configuration file should be set as a 4x4 scenario and each RU would be given a +different beam. The reference DU configuration file is [`gnb-du.sa.band77.273prb.fhi72.4x4-das-benetel650_650.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.4x4-das-benetel650_650.conf). + +DAS is enabled by setting to 1 the parameter `enable_das` in `L1` section. + +The following parameters shall be configured on the gNB in the `MACRLC` section: +- `set_analog_beamforming` +- `beam_duration` +- `beams_per_period` + +For guidance on how to set these parameters please refer to +the [analog beamforming document](./analog_beamforming.md). Next, configure the `fhi_72` section as indicated below: @@ -1202,9 +1210,6 @@ fhi_72 = { ``` -Compare also with the example (DU) configuration in -[`gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650.conf`](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650.conf). - Afterwards, start the gNB with the modified configuration file. If everything went well, you should see the RU counters for both RUs go up: diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 6e46a361fe..d9730c1f27 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -135,7 +135,7 @@ Here are some useful command line options for the NR UE: |--------------------------|---------------------------------------------------------------------------------------------------------------| | `--ue-scan-carrier` | Scan for cells in current bandwidth. This option can be used if the SSB position of the gNB is unknown. If multiple cells are detected, the UE will try to connect to the first cell. By default, this option is disabled and the UE attempts to only decode SSB given by `--ssb`. | | `--ue-fo-compensation` | Enables the initial frequency offset compensation at the UE. Useful when running over the air and/or without an external clock/time source. | -| `--cont-fo-comp` | Enables the continuous frequency offset (FO) estimation and compensation. Parameter value `1` specifies that the main FO contribution comes from the local oscillator's (LO) accuracy. Parameter value `2` specifies that the main FO contribution comes from Doppler shift. | +| `--cont-fo-comp` | Enables the continuous frequency offset (FO) estimation and compensation. Parameter value `1` specifies that the main FO contribution comes from the local oscillator's (LO) accuracy. Parameter value `2` specifies that the main FO contribution comes from Doppler shift. Parameter value `3` specifies that no measured residual DL FO is considered for UL FO pre-compensation. | | `--initial-fo` | Sets the known initial frequency offset. Useful especially with large Doppler frequency, e.g. LEO satellite. | | `--freq-sync-P` | Sets the coefficient for the Proportional part of the PI-controller for the continuous frequency offset compensation. Default value 0.01. | | `--freq-sync-I` | Sets the coefficient for the Integrating part of the PI-controller for the continuous frequency offset compensation. Default value 0.001. | @@ -296,7 +296,6 @@ This allows to reuse HARQ processes immediately, but it breaks compatibility wit To enable this feature, the `disable_harq` flag has to be added to the gNB conf file in the section `gNBs.[0]` ``` ... - sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; // <-- @@ -356,7 +355,9 @@ sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF For LEO satellite scenarios, the parameter `--ntn-initial-time-drift` must be provided via command line, as the UE needs this value to compensate for the time drift during initial sync, before SIB19 was received. This parameter provides the drift rate of the complete DL timing (incl. feeder link and service link) in µs/s. -Also, to perform an autonomous TA update based on the DL drift, the boolean parameter `--autonomous-ta` should be added in case of a LEO satellite scenario. + +To perform an autonomous TA update based on the DL drift, the boolean parameter `--autonomous-ta` can be added. +If that parameter is omitted, the TA is continuously computed based on the SIB19 information. For LEO satellite scenario we assume the LO to be very accurate and the main FO contribution comes from Doppler shift. Therefore, we use the command line parameter `--cont-fo-comp 2` to continuously compensate the DL Doppler and pre-compensate the UL Doppler. @@ -367,7 +368,7 @@ For other information on optional NR UE command line options, please refer [here So an example NR UE command for FDD, 5MHz BW, 15 kHz SCS, transparent LEO satellite 5G NR NTN is this: ``` cd cmake_targets -sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod --time-sync-I 0.1 --ntn-initial-time-drift -46 --autonomous-ta --initial-fo 57340 --cont-fo-comp 2 +sudo ./ran_build/build/nr-uesoftmodem -O ../targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf --band 254 -C 2488400000 --CO -873500000 -r 25 --numerology 0 --ssb 60 --rfsim --rfsimulator.prop_delay 20 --rfsimulator.options chanmod --time-sync-I 0.1 --ntn-initial-time-drift -46 --initial-fo 57340 --cont-fo-comp 2 ``` # Specific OAI modes @@ -468,19 +469,30 @@ The hardcoded DRBs will be treated like GBR Flows. Due to code limitations at th ## IF setup with OAI -OAI is also compatible with Intermediate Frequency (IF) equipment. This allows to use RF front-end that with arbitrary frequencies bands that do not comply with the standardised 3GPP NR bands. +OAI is also compatible with Intermediate Frequency (IF) equipment, allowing the +use of RF front-ends operating on arbitrary frequency bands that do not conform +to the standardized 3GPP NR bands. -To configure the IF frequencies it is necessary to use two command-line options at UE side: -- `if_freq`, downlink frequency in Hz -- `if_freq_off`, uplink frequency offset in Hz +### OAIUE configuration +To configure IF frequencies on the UE side, provide the following command-line +options: +- `if_freq`: DL frequency in Hz +- `if_freq_off`: UL frequency offset in Hz -Accordingly, the following parameters must be configured in the RUs section of the gNB configuration file: -- `if_freq` -- `if_offset` +### gNB configuration +On the gNB side, the corresponding parameters must be set in the RUs section of +the configuration file: +- `if_freq`: DL frequency in Hz +- `if_offset`: UL frequency offset in Hz + +> Note: When using a libconfig-based configuration file for the gNB, ensure that +> `if_freq` numeric value is suffixed with "L" so it is correctly parsed as +> 64-bit integer. ### Run OAI with custom DL/UL arbitrary frequencies -The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 (FDD) at gNB side. +The following example uses DL frequency 2169.080 MHz and UL frequency offset +-400 MHz, with a configuration file for band 66 (FDD) at gNB side. On two separate machines with USRPs, run: diff --git a/doc/RUN_NR_multiple_BWPs.md b/doc/RUN_NR_multiple_BWPs.md deleted file mode 100644 index e8598a0445..0000000000 --- a/doc/RUN_NR_multiple_BWPs.md +++ /dev/null @@ -1,44 +0,0 @@ -# Procedure to add dedicated Bandwidth part (BWP) - -## Contributed by 5G Testbed IISc - -### Developers: Abhijith A, Shruthi S - -# Terminology # - -## Bandwidth part (BWP) ## -Bandwidth Part (BWP) is a set of contiguous Resource Blocks in the resource grid. - -Parameters of a BWP are communicated to UE using RRC parameters: BWP-Downlink and BWP-Uplink. - -A UE can be configured with a set of 4 BWPs in uplink (UL) and downlink (DL) direction (3GPP TS 38.331 Annex B.2 Description of BWP configuration options). But only 1 BWP can be active in UL and DL direction at a given time. - -# Procedure to run multiple dedicated BWPs # - -A maximum of 4 dedicated BWPs can be configured for a UE. - -To configure multiple BWPs, add the following parameters in the physical parameters section: - -## Setup of the Configuration files ## - -In the configuration file you have the option to select the 1st active BWP, the RIV and SCS of each BWP in the following way (example with 3 additional BWPs): -``` - first_active_bwp = 1; - bwp_list = ({ scs = 1; bwpStart = 0; bwpSize = 106;}, - { scs = 1; bwpStart = 0; bwpSize = 51;}, - { scs = 1; bwpStart = 0; bwpSize = 24;}); -``` - -This example configures 3 additional BWPs, with IDs from 1 to 3. Find these parameters in this configuration file: "ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf" - -# Testing gNB and UE in RF simulator - -## gNB command: -``` - sudo ./nr-softmodem -O ../../../ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf --rfsim --rfsimulator.serveraddr server -``` - -## UE command: -``` - sudo ./nr-uesoftmodem -C 3319680000 -r 106 --numerology 1 --ssb 516 --band 78 --rfsim --rfsimulator.serveraddr 127.0.0.1 -``` diff --git a/doc/analog_beamforming.md b/doc/analog_beamforming.md index 45f93bf44c..6a11a9f94a 100644 --- a/doc/analog_beamforming.md +++ b/doc/analog_beamforming.md @@ -24,7 +24,7 @@ In the `MACRLC` section of configuration files, there are three new parameters: Setting analog beamforming to 1 or 2 changes the way FAPI beam index is treated. By setting 1, we instruct L1 to look up in Hi-PHY preconfigured DBM beam index. By setting 2, we instruct L2 to directly signal to Lo-PHY the beam index (e.g. over 7.2x fronthaul). -DAS is enabled by setting to 1 the parameter `enable_das` in the L1 section of the configuration file. In case of DAS enabled, the field `beam_weights` in `MACRLC` section can be omitted. +DAS is enabled by setting to 1 the parameter `enable_das` in the L1 section of the configuration file. In case of DAS enabled, the field `beam_weights` in `MACRLC` section can be omitted and the number of beams per period equals the total number of beams. # Implementation in OAI scheduler @@ -34,17 +34,26 @@ To this goal, we extended the virtual resource block (VRB) map by one dimension It is important to note that in current implementation, there are several periodical channels, e.g. PRACH or PUCCH for CSI et cetera, that have the precendence in being assigned a beam, that is because the scheduling is automatic, set in RRC configuration, and not up to the scheduler. For these instances, we assume the beam is available (if not there are assertions to stop the process). For data channels, the currently implemented PF scheduler is used. The only modification is that a UE can be served only if there is a free beam available or the one of the beams already in use correspond to that UE beam. +## Beams in phy-test scheduler + +In phy-test mode, beams are assigned to PDSCH slots in the same manner as SSB slots with the only addition that it repeats for every TDD period in a frame. For example if PDSCH is scheduled on all DL slot for TDD format DDDDDDDSUU, and with SSB bit map = `0b1010101` and the following beam parameters in config file, +- `beam_weights` = [10,11,12,13] +- `beam_duration` = 1 +- `beams_per_period` = 1 + +The DL slots in every TDD period will have beams 10,11,12,13,0,0,0 + # FAPI implementation -To be noted that in our implementation analog beamforming is only supported in non-split/monolithic mode because we don't support yet SCF P19 interface that would be needed to manage these procedure in a split scenario with SCF FAPI. +To be noted that in our implementation analog beamforming is only partially supported in split mode. +The index based beamforming relies on the Tx precoding and beamforming PDU definition of beam-ID, where MSB is used to signal if the ID can be directly used or is it a pointer to a pre-stored vector of weights. +This definition of beam-ID is present only in the most recent versions of SCF PHY API specifications (at least from v8 and later, possibly from v6). -In `config_request` structure, a vendor extension (`nfapi_nr_analog_beamforming_ve_t`) configures the lower layers at initialization with the following information: +In addition to that, a `config_request` structure defined as vendor extension (`nfapi_nr_analog_beamforming_ve_t`) configures the lower layers at initialization with the following information: - `analog_bf_vendor_ext` which can assume values 1 or 0 for enabling or disabling analog beamforming - `num_beams_period_vendor_ext` which corresponds to the configuration parameter `beams_per_period` -- `total_num_beams_vendor_ext` which corresponds to the number of beams configured in `beam_weights` -- `analog_beam_list` which contains the RU beamforming indices configured in `beam_weights` -Additionally, L2 provides in each channel FAPI message information about the beam index. Small Cell Forum (SCF) FAPI provides in its PHY API specifications for the channels only a field for digital beamforming as part of the `precoding_and_beamforming` stucture. Therefore without a better option, we are currently using that one to store the internal analog beamforming index. This is the index used internally by the code to progressively identify the beam with a value from 0 to `total_num_beams_vendor_ext`. +Therefore, in case of analog beamforming, L2 provides in each channel FAPI message information about the beam index via the beam-ID parameter with MSB set to 1. # L1 implementation diff --git a/doc/cross-compile.md b/doc/cross-compile.md index 79c4bae761..20edec65b8 100644 --- a/doc/cross-compile.md +++ b/doc/cross-compile.md @@ -89,7 +89,7 @@ be defined in order to tell cmake where the host tools have been built. cd ../build-cross cmake ../../.. -GNinja -DCMAKE_TOOLCHAIN_FILE=../../../cmake_targets/cross-arm.cmake -DNATIVE_DIR=../build -ninja dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim +ninja dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_srssim ninja lte-softmodem nr-softmodem nr-cuup oairu lte-uesoftmodem nr-uesoftmodem ninja params_libconfig coding rfsimulator ``` diff --git a/doc/environment-variables.md b/doc/environment-variables.md index 767afa6db4..6fb7b884ae 100644 --- a/doc/environment-variables.md +++ b/doc/environment-variables.md @@ -9,7 +9,8 @@ OAI uses/supports a number of environment variables, documented in the following - `NVRAM_DIR`: directory to read/write NVRAM data in (5G) `nvram` tool; if not defined, will use `PWD` (working directory) - `OAI_CONFIGMODULE`: can be used to pass the configuration file instead of `-O` - `OAI_GDBSTACKS`: if defined when hitting an assertion (`DevAssert()`, `AssertFatal()`, ...), OAI will load `gdb` and provide a backtrace for every thread -- `OAI_RNGSEED`: overwrites any seed for random number generators (RNG) in simulators +- `OAI_RNGSEED`: provide a fixed seed for random number generators (RNG). If + this variable is absent, a random seed will be read (from `/dev/urandom`). - `USIM_DIR`: directory to read/write USIM data in (4G) `usim` tool; if not defined, will use `PWD` (working directory) Furthermore, these variables appear in code that is not maintained and maybe not even compiled anywhere: diff --git a/doc/handover-tutorial.md b/doc/handover-tutorial.md index b6e60746aa..92762f7d88 100644 --- a/doc/handover-tutorial.md +++ b/doc/handover-tutorial.md @@ -1,6 +1,15 @@ This tutorial explains how to perform handovers. It covers both F1 handovers (intra-gNB, within a single gNB between DUs) and N2 handovers (inter-gNB). +This document assumes familiarity with the F1 split architecture and basic +OAI knowledge. Please refer to the prerequisite documentation listed below: + +- To run the [Core Network](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/NR_SA_Tutorial_OAI_CN5G.md) +- To run [OAI full stack with COTS UE](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/NR_SA_Tutorial_COTS_UE.md) +- [F1 split design document](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/F1AP/F1-design.md?ref_type=heads) +for details on the F1 architecture and the networking relationships between +the CU and the associated DUs. + [[_TOC_]] # Considered setup for F1 handover @@ -13,22 +22,22 @@ same. ![F1 Handover setup](./RRC/ho.png) -# What is a gNB neighbor? +# gNB neighbour definition -Network continuity is a key aspect of 5G. In the 5G architecture, gNB neighbors +Network continuity is a key aspect of 5G. In the 5G architecture, gNB neighbours play a central role in maintaining service continuity through mechanisms such -as handover and load balancing. By definition, a gNB neighbor is another gNB +as handover and load balancing. By definition, a gNB neighbour is another gNB that can be measured and linked by the UE. If the current serving gNB is no -longer optimal, the UE may connect to a neighbor gNB. +longer optimal, the UE may connect to a neighbour gNB. To support this behavior, the network configuration specifies additional frequencies and cells that the UE should measure. The UE reports these measurements to the network, which then decides whether or not to initiate a handover. -Neighbor types include: -- **Intra-gNB neighbors** - cells belonging to the same gNB -- **Inter-gNB neighbors** - cells belonging to different gNBs -- **Inter-RAT neighbors** - cells belonging to another RAT (e.g., LTE) +Neighbour types include: +- **Intra-gNB neighbours** - cells belonging to the same gNB +- **Inter-gNB neighbours** - cells belonging to different gNBs +- **Inter-RAT neighbours** - cells belonging to another RAT (e.g., LTE) # Steps to run F1 handover with OAI UE @@ -46,10 +55,6 @@ build both gNB and UE as well as activate the build of telnet to that purpose: ## Run the setup -This tutorial assumes you have a core network running; [refer to the -corresponding tutorial](./NR_SA_Tutorial_OAI_CN5G.md) if this is not the case -yet. - We will use the TDD configuration files in the repository for the [CU](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-cu.sa.f1.conf) as well for [DU0](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band78.106prb.rfsim.pci0.conf) @@ -139,19 +144,23 @@ directory of the CU. You can do handover across DUs with a COTS UE. Note that these DUs should be separated by at least multiple meters to ensure that the UE will receive different signal strengths when moving between cells. +In the CI setup we use a digital 4 channel attenuator that allows us to "control" +the transmitted signal from both RUs. This allows us to create a setup in +which the UE thinks it's changing positions between 2 cells, but in reality +it's not moving. -We support both intra-frequency and inter-frequency handovers. We have verified with USRPs -only, although other radios should work as well. +We support both intra-frequency and inter-frequency handovers. We have verified +with USRPs only, although other radios should work as well. -For UEs, we verified Quectel modules and iPhones. Note, though, that not all -phones might work; for instance, we did not achieve handovers with a OnePlus -Nord, yet. +For UEs, we verified Quectel modules, iPhones and Samsung S23 Ultra. Note, +though, that not all phones might work; for instance, we did not achieve +handovers with a OnePlus Nord, yet. ## Steps -First, make sure that you can run both DUs with the CU independently. Use the -same radio hardware for both radios to ensure that both cells can be received -equally good by the UE. +First, make sure that you can run both DUs with the CU independently. +Use the same radio hardware for both radios to ensure that both cells can be +received equally good by the UE. In order to enable handovers (triggered by the UE), you have to configure the neighbour relation of the DUs at the CU. To do so, proceed as follows: @@ -163,11 +172,13 @@ neighbour relation of the DUs at the CU. To do so, proceed as follows: ``` cat nrRRC_stats.log ``` -1. Fill in the [`neighbour-config.conf`](../ci-scripts/conf_files/neighbour-config.conf) configuration file as shown below, and - `@include` it in the CU file. -1. Start the CU and both DUs. +1. Fill in the [`neighbour-config.conf`](../ci-scripts/conf_files/neighbour-config.conf) + configuration file as shown below, and `@include` it in the CU file. +1. Start the CU and both DUs. If you are using an attenuator, make sure that + the signal on one DU is stronger than the other. + 1. Bring the phone close to one cell, and leave flight mode. It should connect - to the DU to which it is closer. + to the DU to which it is closer/stronger signal. 1. Move the UE towards the other DU; it should trigger an "A3 event" (Neighbour Becomes Better than Serving), and the CU will trigger the handover to the other DU. @@ -175,7 +186,14 @@ neighbour relation of the DUs at the CU. To do so, proceed as follows: The output on the terminal should be the same as with RFsim. If no handover is triggered: -- Make sure that both DUs use the same hardware. +- Make sure that both DUs use the same hardware. In case of USRPs, make sure that + they are synched: + - By connecting them to a GPS or an Octoclock to provide a common time and clock + reference. + - By synchronizing the RU hosts. + - By using Openairinterface starting tag [2025.w42](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tree/2025.w42?ref_type=tags) + (A fix was added to force the USRP to "use" the time/clock provided by the + external source instead to its own master clock. for more info see [MR](https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/3693)). - Make sure that the UE sees both cells. For instance, you can switch to flight mode, go closer to the other DU, and switch off flight mode -- the UE should connect to that second DU. @@ -187,6 +205,17 @@ decision about a handover is always at the network-side, the UE only "assists" through measurements telling the CU that one DU is stronger than others. Hence, "forcing" a handover just means that you manually trigger the handover, instead of waiting for UE measurement report.) + +Our CI setup consists of: +- 2 USRPs B210 that are synchronized by connecting them to an Octoclock over + 10MHz refrence and a PPS signal. The RU hosts are synchronized via NTP. +- Mini-Circuits RC4DAT-6G-60 programmable attenuator. To control the digital + attenuator, a Python script was developed `ci-scripts/attenuatorctl.py`. +- Quectel RM520 as a UE. +- The setup is run using Docker `ci-scripts/yaml_files/5g_sa_f1_b210_ho`. + +To run the setup using Docker: +- We consider 2 synchronized servers. One for each DU. ## Example neighbour configuration @@ -209,70 +238,101 @@ Concretely, the first cell is `12345678` (on DU `[2]`), and it has `11111111` The below configuration further enables periodic measurements, A2 event ("Serving becomes worse than threshold"), and A3 events ("Neighbour Becomes -Better than Serving"). The A2 event can be disabled by setting `enable = 0`. A3 -events cannot be disabled as of now. Further, the A3 events can be made -specific to cells; `cell_id = -1` means "any cell". +Better than Serving"). +The A2 event can be disabled by setting `enable = 0`. +The A3 event cannot be disabled as of now. It can be made +specific to cells or set to `physCellId = -1` which means "any cell". +`hysteresis` is a margin added to the serving cell measurements to +prevent unnecessary or frequent handovers. It ensures that the neighbouring +cell must show sufficiently better signal quality before a handover is +triggered. It is an integer between 0 and 30. + +`time_to_trigger` the time during which specific criteria for the event +needs to be met in order to trigger a measurement report. It is an enumerated +parameter and in the configuration below it is set to 1 which corresponds to +`ms40` or 40 milliseconds. + +*Note*: For more information please refer to 3GPP TS 38.331 specifications. ``` -neighbour_list = ( - { - nr_cellid = 12345678; - neighbour_cell_configuration = ( - { - gNB_ID = 0xe01; - nr_cellid = 11111111; - physical_cellId = 1; - absoluteFrequencySSB = 643296; - subcarrierSpacing = 1; #30 KHz - band = 78; - plmn = { mcc = 001; mnc = 01; mnc_length = 2}; - tracking_area_code = 1; - } - ) - }, - { - nr_cellid = 11111111; - neighbour_cell_configuration = ( - { - gNB_ID = 0xe00; - nr_cellid = 12345678; - physical_cellId = 0; - absoluteFrequencySSB = 643296; - subcarrierSpacing = 1; #30 KHz - band = 78; - plmn = { mcc = 001; mnc = 01; mnc_length = 2}; - tracking_area_code = 1; - } - ) - } - ); +############################################################ +# gNB-to-gNB neighbour list + measurement configuration # +# for the 2-cell rfsim setup (gNB_ID 0xe00 & 0xb00) # +############################################################ +neighbour_list = ( + ########################################################## + # Entry USED BY gNB_ID = 0xe00 (nr_cellid = 12345678L) # + ########################################################## + { + nr_cellid = 12345678; # Serving cell of gNB 0xe00 + neighbour_cell_configuration = ( + { + gNB_ID = 0xe01; + nr_cellid = 11111111; # Cell served by gNB 0xe01 + physical_cellId = 1; + absoluteFrequencySSB = 643296; + subcarrierSpacing = 1; # 30 kHz + band = 77; + plmn = { mcc = 001; mnc = 01; mnc_length = 2 }; + tracking_area_code = 1; + } + ); + }, + + ########################################################## + # Entry USED BY gNB_ID = 0xe01 (nr_cellid = 11111111) # + ########################################################## + { + nr_cellid = 11111111; # Serving cell of gNB 0xe01 + neighbour_cell_configuration = ( + { + gNB_ID = 0xe00; + nr_cellid = 12345678L; # Cell served by gNB 0xe00 + physical_cellId = 0; + absoluteFrequencySSB = 643296; + subcarrierSpacing = 1; # 30 kHz + band = 77; + plmn = { mcc = 001; mnc = 01; mnc_length = 2 }; + tracking_area_code = 1; + } + ); + } +); + +############################################################ +# Common NR measurement-event configuration # +############################################################ nr_measurement_configuration = { Periodical = { - enable = 1; - includeBeamMeasurements = 1; - maxNrofRS_IndexesToReport = 4; + enable = 1; + includeBeamMeasurements = 1; + maxNrofRS_IndexesToReport = 4; }; A2 = { - enable = 1; - threshold = 60; - timeToTrigger = 1; + enable = 1; + threshold = 60; + time_to_trigger = 1; }; - A3 = ({ - cell_id = -1; #Default - offset = 10; - hysteresis = 0; - timeToTrigger = 1 - }) + A3 = ( + { + physCellId = -1; + offset = 10; + hysteresis = 0; + time_to_trigger = 1; + } + ) }; ``` -`@include` this configuration file inside the gNB section of CU file as shown below. + +`@include` this configuration file inside the gNB section of CU file as shown +below. ``` - plmn_list = ({ mcc = 222; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff })}); + plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff })}); @include "neighbour-config.conf" @@ -331,7 +391,7 @@ are as follows: on UTC time or a timer-based solution, which can also be applied jointly (or not) with another trigger as the measurement-based trigger. The timer-based handover trigger considers the deterministic satellite movement to predict - the time duration for which the satellite’s footprint covers a certain zone. + the time duration for which the satellite's footprint covers a certain zone. - **Timing advance value-based triggering**: This method uses the timing advance value (independently or jointly with another trigger) to trigger a @@ -364,30 +424,37 @@ done ## Run the setup -An N2 handover involves the transfer of a UE from one gNB to another via the 5G core network. Unlike F1 handover, where the CU handles the process internally between its DUs, N2 handover requires signaling through the AMF, making it a core-network-based handover. +An N2 handover involves the transfer of a UE from one gNB to another via the +5G core network. Unlike F1 handover, where the CU handles the process internally +between its DUs, N2 handover requires signaling through the AMF, making it +a core-network-based handover. We assume: * Two independent gNBs connected to the same 5GC via N2 interface. * A UE initially connected to gNB-PCI0, which will be handed over to gNB-PCI1. -* Handover is triggered by either a decision based measurement event (e.g. A3) or telnet command. +* Handover is triggered by either a decision based measurement event (e.g. A3) +or telnet command. ## Steps to run N2 handover with OAI UE -**Note for same-machine setup:** When running both gNBs on the same machine, you need to assign a unique IP address to the second gNB to avoid network conflicts. For example: +**Note for same-machine setup:** When running both gNBs on the same machine, +you need to assign a unique IP address to the second gNB to avoid network +conflicts. For example: ```sh sudo ip addr add 192.168.71.180/24 dev rfsim5g-public ``` -1. Similarly to F1 handover, UE does not support any measurement reporting and handover is triggered by -telnet command. Therefore, ensure that both gNBs and UE are built with telnet support: +1. Similarly to F1 handover, UE does not support any measurement reporting and +handover is triggered by telnet command. Therefore, ensure that both gNBs and +UE are built with telnet support: ```sh ./build_oai --ninja --nrUE --gNB --build-lib telnetsrv ``` -Run the 5G Core Network if not already running. See [OAI CN5G tutorial](./NR_SA_Tutorial_OAI_CN5G.md). +Run the 5G Core Network if not already running. 2. Start the source gNB (gNB-PCI0) e.g. @@ -409,7 +476,8 @@ Ensure the UE successfully registers with the network. sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.pci1.rfsim.conf --rfsim --telnetsrv --telnetsrv.shrmod ci --gNBs.[0].min_rxtxtime 6 --rfsimulator.serveraddr 127.0.0.1 ``` -**Note for same-machine setup:** When running both gNBs on the same machine, add the following network interface options to the target gNB command, e.g.: +**Note for same-machine setup:** When running both gNBs on the same machine, +add the following network interface options to the target gNB command, e.g.: ```sh --gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NG_AMF 192.168.71.180 @@ -423,96 +491,20 @@ From gNB-PCI0, trigger handover on target gNB with PCI 1 for UE ID 1: ```sh echo ci trigger_n2_ho 1,1 | nc 127.0.0.1 9090 && echo ``` -where the input parameters correspond to the PCI of the neighbor cell and the RRC ID of the UE. +where the input parameters correspond to the PCI of the neighbor cell and the +RRC ID of the UE. This will initiate the N2 handover on the source gNB. ## Neighbour list and measurement configuration -Make sure the configuration file contains a neighbour list and measurement configuration, e.g. [neighbour-config-rfsim.conf](../../ci-scripts/conf_files/neighbour-config.conf). This configuration can also be present in a different file and included in the gNB configuration file with `@include "neighbour-config-rfsim.conf"`. +Make sure the configuration file contains a neighbour list and measurement +configuration, e.g. [neighbour-config-rfsim.conf](../../ci-scripts/conf_files/neighbour-config.conf). +This configuration can also be present in a different file and included in the +gNB configuration file with `@include "neighbour-config-rfsim.conf"`. -For each gNB there is a `neighbour_cell_configuration` linked to its serving cell ID. +For each gNB there is a `neighbour_cell_configuration` linked to its serving +cell ID. -The measurement configuration is based on A2 and A3 measurement events in 5G NR. These events are used by the UE to report radio conditions to the gNB. The A2 Measurement Event indicates that the serving cell’s signal quality has degraded below a defined threshold and the UE shall initiate measurement of neighboring cells. The A3 Measurement Event indicates that a neighboring cell’s signal quality is better than that of the serving cell by a certain offset and the UE shall trigger handover to a stronger neighboring cell - -This is an example with comments on how to use the configuration file: - -``` -############################################################ -# gNB-to-gNB neighbour list + measurement configuration # -# for the 2-cell rfsim setup (gNB_ID 0xe00 & 0xb00) # -############################################################ - -neighbour_list = ( - ########################################################## - # Entry USED BY gNB_ID = 0xe00 (nr_cellid = 12345678L) # - ########################################################## - { - nr_cellid = 12345678L; # Serving cell of gNB 0xe00 - neighbour_cell_configuration = ( - { - gNB_ID = 0xb00; - nr_cellid = 720898; # Cell served by gNB 0xb00 - physical_cellId = 1; - absoluteFrequencySSB= 621312; - subcarrierSpacing = 1; # 30 kHz - band = 78; - plmn = { mcc = 208; mnc = 99; mnc_length = 2 }; - tracking_area_code = 1; - } - ); - }, - - ########################################################## - # Entry USED BY gNB_ID = 0xb00 (nr_cellid = 720898) # - ########################################################## - { - nr_cellid = 720898; # Serving cell of gNB 0xb00 - neighbour_cell_configuration = ( - { - gNB_ID = 0xe00; - nr_cellid = 12345678L; # Cell served by gNB 0xe00 - physical_cellId = 0; - absoluteFrequencySSB= 641280; - subcarrierSpacing = 1; # 30 kHz - band = 78; - plmn = { mcc = 208; mnc = 99; mnc_length = 2 }; - tracking_area_code = 1; - } - ); - } -); - -############################################################ -# Common NR measurement-event configuration # -############################################################ - -nr_measurement_configuration = { - Periodical = { - enable = 1; - includeBeamMeasurements = 1; - maxNrofRS_IndexesToReport = 4; - }; - - A2 = { - enable = 1; - threshold = 60; - timeToTrigger = 1; - }; - - A3 = ( - { - cell_id = 720898; # neighbour of gNB 0xe00 - offset = 10; - hysteresis = 0; - timeToTrigger = 1; - }, - { - cell_id = 12345678; # neighbour of gNB 0xb00 - offset = 5; - hysteresis = 1; - timeToTrigger = 2; - } - ); -}; -``` +See the example above for `neighbour-config-ho.conf`. The same configuration +is for both F1 and N2 handover. diff --git a/doc/nfapi.md b/doc/nfapi.md index b901b15269..5f2d8a35da 100644 --- a/doc/nfapi.md +++ b/doc/nfapi.md @@ -1,3 +1,5 @@ +# FAPI/nFAPI split in OAI + This document describes the SmallCellForum (SCF) (n)FAPI split in 5G, i.e., between the MAC/L2 and PHY/L1. It also describes how to make use of the multiple transport mechanisms between the 2. @@ -10,7 +12,7 @@ about nFAPI can be found in SCF 225.2.0. [[_TOC_]] -# Quickstart +## Quickstart Compile OAI as normal. Start the CN and make sure that the VNF configuration matches the PLMN/IP addresses. Then, run the VNF @@ -29,7 +31,7 @@ VNF!) You should not observe a difference between nFAPI split and monolithic. -# Status +## Status All FAPI message can be transferred between VNF and PNF. This is because OAI uses FAPI with its corresponding messages internally, whether a split is in use @@ -54,7 +56,7 @@ When using RFsim, the system might run slower than in monolithic. This is because the PNF needs to slow down the execution time of a specific slot, because it has to send a Slot.indication to the VNF for scheduling. -# Configuration +## Configuration Both PNF and VNF are run through the `nr-softmodem` executable. The type of mode is switched through the `--nfapi` switch, with options `MONOLITHIC` @@ -173,6 +175,26 @@ After installing WLS, you can run the build command as shown below: Refer to the above steps in [Quickstart](#quickstart), but run the PNF first as it is the WLS "master". +To optimize the performance of your setup, you can provide the option +`--thread-pool ` in the PNF command line. This allows +you to pin PNF processing threads to specific CPU cores, as they might +otherwise interfere with DPDK used by WLS. + +Before selecting which CPU cores to allocate: run `nr-softmodem` without the +`--thread-pool` option and use a process monitoring tool such as htop to check +CPU availability. Check for lightly loaded cores, and use them in the +thread-pool for the PNF. + +Example commands for running an OTA test with USRP B200 on 40MHz: + +Run PNF + + sudo NFAPI_TRACE_LEVEL=info ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-pnf.band78.rfsim.conf --nfapi PNF --continuous-tx -E --thread-pool 1,2,3,4,5 + +Run VNF + + sudo NFAPI_TRACE_LEVEL=info ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.106prb.nfapi.conf --nfapi VNF + #### How to run OAI PNF with OSC/Radisys O-DU Set up the hugepages for DPDK (1GB page size, 6 pages; this only needs to be @@ -236,7 +258,7 @@ Run the OAI-UE sudo ./nr-uesoftmodem -r 273 --numerology 1 --band 78 -C 3400140000 --ssb 1518 --uicc0.imsi 001010000000001 --rfsim -# nFAPI logging system +## nFAPI logging system nFAPI has its own logging system, independent of OAI's. It can be activated by setting the `NFAPI_TRACE_LEVEL` environment variable to an appropriate value; @@ -263,3 +285,26 @@ done over virtual time, i.e., frames/slots as executed by the 5G Systems. For instance, these numbers might be slightly higher or slower in RFsim than in wall-clock time, depending if the system advances faster or slower than wall-clock time. + +## Troubleshoot + +When operating using the FAPI split, the PNF needs to give the VNF extra time +to schedule the next slot. Especially since the current nFAPI split still +relies on slot indications, extra time due to transport delays need to be +accounted for. Currently, this delay is set conservatively, meaning that it +should work for most systems, but can create problems during random access: + + [NR_MAC] exceeded RA window: preamble at 411.19 now 413.0 (diff 21), ra_ResponseWindow 5/20 slots + [NR_MAC] sfn: 413.0 UE RA-RNTI 010b TC-RNTI 5d82: exceeded RA window, cannot schedule Msg2 + +means that the VNF received a preamble (411.19), but the current slot to be +scheduled (413.0) is beyond the random access response window (20 slots). In +this case, try one of the following: + +- If the radio allows, reduce the L1 TX advance `RUs.[0].sl_ahead` by some + slots, but note that this could make the system less stable. +- Change the code to reduce `sl_ahead` inside function `handle_nr_slot_ind()`, + to reduce the FAPI scheduling slot time budget. +- Non-standard: You can manually increase the response window by setting + `gNBs.[0].servingCellConfigCommon.[0].ra_ResponseWindow` to, e.g., 6. Note + that the maximum allowed response window is 10ms. diff --git a/doc/physical-simulators.md b/doc/physical-simulators.md index b74531fd20..0f000bb16f 100644 --- a/doc/physical-simulators.md +++ b/doc/physical-simulators.md @@ -36,6 +36,7 @@ pipelines: | | `nr_pbchsim` | Broadcast channel simulation | | | `nr_prachsim` | PRACH simulation | | | `nr_psbchsim` | Sidelink simulation | +| | `nr_srssim` | SRS simulation | | Coding | `ldpctest`, `polartest`, `smallblocktest` | LDPC, Polar, and other FEC tests | ## Source Locations diff --git a/docker/Dockerfile.base.rhel9 b/docker/Dockerfile.base.rhel9 index dde540556b..e57c705471 100644 --- a/docker/Dockerfile.base.rhel9 +++ b/docker/Dockerfile.base.rhel9 @@ -73,6 +73,10 @@ ENV TINI_VERSION=v0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${TARGETARCH} /tini RUN chmod +x /tini +ENV YQ_VERSION=v4.2.0 +RUN wget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${TARGETARCH} -O /usr/local/bin/yq &&\ + chmod +x /usr/local/bin/yq + # In some network environments, GIT proxy is required RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi" diff --git a/docker/Dockerfile.base.rocky b/docker/Dockerfile.base.rocky index 98a9ef703a..d34dcdafc6 100644 --- a/docker/Dockerfile.base.rocky +++ b/docker/Dockerfile.base.rocky @@ -66,6 +66,10 @@ ENV TINI_VERSION=v0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${TARGETARCH} /tini RUN chmod +x /tini +ENV YQ_VERSION=v4.2.0 +RUN wget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${TARGETARCH} -O /usr/local/bin/yq &&\ + chmod +x /usr/local/bin/yq + # Copying only the needed files to create ran-base WORKDIR /oai-ran/cmake_targets/tools COPY cmake_targets/tools/build_helper \ diff --git a/docker/Dockerfile.gNB.aerial.ubuntu b/docker/Dockerfile.gNB.aerial.ubuntu index 04bed658fe..b79ab78fa8 100644 --- a/docker/Dockerfile.gNB.aerial.ubuntu +++ b/docker/Dockerfile.gNB.aerial.ubuntu @@ -110,6 +110,8 @@ RUN ldconfig && \ /usr/local/lib/libnvipc.so WORKDIR /opt/oai-gnb + +COPY --from=ran-build /usr/local/bin/yq /usr/local/bin/yq COPY --from=ran-build /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.aw2s.rhel9 b/docker/Dockerfile.gNB.aw2s.rhel9 index 65eafac37b..e35b0a7690 100644 --- a/docker/Dockerfile.gNB.aw2s.rhel9 +++ b/docker/Dockerfile.gNB.aw2s.rhel9 @@ -101,6 +101,7 @@ RUN ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/libthirdparty_tra WORKDIR /opt/oai-gnb-aw2s +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb-aw2s/bin/entrypoint.sh"] CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.aw2s.rocky b/docker/Dockerfile.gNB.aw2s.rocky index 1c0adfccd8..d1f567cb42 100644 --- a/docker/Dockerfile.gNB.aw2s.rocky +++ b/docker/Dockerfile.gNB.aw2s.rocky @@ -51,7 +51,8 @@ RUN dnf update -y && \ lksctp-tools \ tzdata \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -95,6 +96,7 @@ RUN ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/libthirdparty_tra WORKDIR /opt/oai-gnb-aw2s +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb-aw2s/bin/entrypoint.sh"] CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.aw2s.ubuntu b/docker/Dockerfile.gNB.aw2s.ubuntu index b55977dfab..840b4a8a28 100644 --- a/docker/Dockerfile.gNB.aw2s.ubuntu +++ b/docker/Dockerfile.gNB.aw2s.ubuntu @@ -95,6 +95,7 @@ RUN /bin/bash -c "ln -s /usr/local/lib/libaw2sori_transpro.so /usr/local/lib/lib WORKDIR /opt/oai-gnb-aw2s +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb-aw2s/bin/entrypoint.sh"] CMD ["/opt/oai-gnb-aw2s/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.fhi72.rhel9 b/docker/Dockerfile.gNB.fhi72.rhel9 index 122b3b668d..bda79eba28 100644 --- a/docker/Dockerfile.gNB.fhi72.rhel9 +++ b/docker/Dockerfile.gNB.fhi72.rhel9 @@ -126,6 +126,8 @@ RUN ldconfig && \ /opt/phy/fhi_lib/lib/build/libxran.so WORKDIR /opt/oai-gnb + +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.fhi72.rocky b/docker/Dockerfile.gNB.fhi72.rocky index f95310059d..ba7861d1bf 100644 --- a/docker/Dockerfile.gNB.fhi72.rocky +++ b/docker/Dockerfile.gNB.fhi72.rocky @@ -49,7 +49,8 @@ RUN dnf update -y && \ python3 \ python3-pip \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ pip3 install six && \ pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -114,6 +115,8 @@ RUN ldconfig && \ /opt/phy/fhi_lib/lib/build/libxran.so WORKDIR /opt/oai-gnb + +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.fhi72.ubuntu b/docker/Dockerfile.gNB.fhi72.ubuntu index fb9d1d43f7..09af53eed5 100644 --- a/docker/Dockerfile.gNB.fhi72.ubuntu +++ b/docker/Dockerfile.gNB.fhi72.ubuntu @@ -111,6 +111,8 @@ RUN ldconfig && \ /opt/phy/fhi_lib/lib/build/libxran.so WORKDIR /opt/oai-gnb + +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.rhel9 b/docker/Dockerfile.gNB.rhel9 index 1c201eeeab..4e766bd011 100644 --- a/docker/Dockerfile.gNB.rhel9 +++ b/docker/Dockerfile.gNB.rhel9 @@ -130,6 +130,7 @@ WORKDIR /opt/oai-gnb #EXPOSE 50000/udp # IF5 / ORI (control) #EXPOSE 50001/udp # IF5 / ECPRI (data) +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.rocky b/docker/Dockerfile.gNB.rocky index d005c36c9f..641dddfc0b 100644 --- a/docker/Dockerfile.gNB.rocky +++ b/docker/Dockerfile.gNB.rocky @@ -47,7 +47,8 @@ RUN dnf update -y && \ python3 \ python3-pip \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ pip3 install six && \ pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -124,6 +125,7 @@ WORKDIR /opt/oai-gnb #EXPOSE 50000/udp # IF5 / ORI (control) #EXPOSE 50001/udp # IF5 / ECPRI (data) +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.gNB.ubuntu b/docker/Dockerfile.gNB.ubuntu index 2259aa39c9..c88857f2d6 100644 --- a/docker/Dockerfile.gNB.ubuntu +++ b/docker/Dockerfile.gNB.ubuntu @@ -128,6 +128,7 @@ WORKDIR /opt/oai-gnb #EXPOSE 50000/udp # IF5 / ORI (control) #EXPOSE 50001/udp # IF5 / ECPRI (data) +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.nr-cuup.rhel9 b/docker/Dockerfile.nr-cuup.rhel9 index b1b083e57c..e21c084c52 100644 --- a/docker/Dockerfile.nr-cuup.rhel9 +++ b/docker/Dockerfile.nr-cuup.rhel9 @@ -35,6 +35,9 @@ RUN cp /oai-ran/docker/scripts/gnb_entrypoint.sh /oai-ran/docker/scripts/entrypo FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-nr-cuup ENV TZ=Europe/Paris +# Install EPEL +RUN dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm + RUN yum repolist --disablerepo=* && \ yum update -y && \ yum install -y \ @@ -42,7 +45,8 @@ RUN yum repolist --disablerepo=* && \ lksctp-tools \ tzdata \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -55,6 +59,7 @@ COPY --from=gnb-build \ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ COPY --from=gnb-base \ @@ -73,6 +78,7 @@ WORKDIR /opt/oai-gnb/etc WORKDIR /opt/oai-gnb +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-cuup", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/docker/Dockerfile.nr-cuup.rocky b/docker/Dockerfile.nr-cuup.rocky index 7f0e8fc2f1..4e87797fd0 100644 --- a/docker/Dockerfile.nr-cuup.rocky +++ b/docker/Dockerfile.nr-cuup.rocky @@ -43,7 +43,8 @@ RUN yum repolist --disablerepo=* && \ lksctp-tools \ tzdata \ net-tools \ - iputils && \ + iputils \ + yaml-cpp-devel && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf @@ -56,6 +57,7 @@ COPY --from=gnb-build \ COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ COPY --from=gnb-base \ @@ -71,6 +73,7 @@ WORKDIR /opt/oai-gnb/etc WORKDIR /opt/oai-gnb +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-cuup", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/docker/Dockerfile.nr-cuup.ubuntu b/docker/Dockerfile.nr-cuup.ubuntu index 2c3c58e7e3..33fd01ab0e 100644 --- a/docker/Dockerfile.nr-cuup.ubuntu +++ b/docker/Dockerfile.nr-cuup.ubuntu @@ -42,7 +42,8 @@ RUN apt-get update && \ libconfig9 \ iproute2 \ net-tools \ - openssl && \ + openssl \ + libyaml-cpp-dev && \ # if the --sanitize option was used to build, additional packages are required /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \ libasan8 \ @@ -61,6 +62,7 @@ COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh COPY --from=gnb-build \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ + /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /usr/local/lib/ RUN ldconfig && ldd /opt/oai-gnb/bin/nr-cuup @@ -69,6 +71,8 @@ RUN ldconfig && ldd /opt/oai-gnb/bin/nr-cuup WORKDIR /opt/oai-gnb/etc WORKDIR /opt/oai-gnb + +COPY --from=gnb-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=gnb-base /tini /tini ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-cuup", "-O", "/opt/oai-gnb/etc/gnb.conf"] diff --git a/docker/Dockerfile.nrUE.rhel9 b/docker/Dockerfile.nrUE.rhel9 index 0929ab3df0..79f44dfafb 100644 --- a/docker/Dockerfile.nrUE.rhel9 +++ b/docker/Dockerfile.nrUE.rhel9 @@ -122,6 +122,8 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai /usr/local/lib64/libuhd.so.4.8.0 WORKDIR /opt/oai-nr-ue + +COPY --from=nr-ue-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=nr-ue-base /tini /tini CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/docker/Dockerfile.nrUE.rocky b/docker/Dockerfile.nrUE.rocky index bfe84dc011..6575d1e3bf 100644 --- a/docker/Dockerfile.nrUE.rocky +++ b/docker/Dockerfile.nrUE.rocky @@ -48,7 +48,8 @@ RUN dnf update -y && \ python3 \ python3-pip \ libXpm \ - libX11 && \ + libX11 \ + yaml-cpp-devel && \ pip3 install six && \ pip3 install requests && \ echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ @@ -119,6 +120,8 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai /usr/local/lib64/libuhd.so.4.8.0 WORKDIR /opt/oai-nr-ue + +COPY --from=nr-ue-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=nr-ue-base /tini /tini CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/docker/Dockerfile.nrUE.ubuntu b/docker/Dockerfile.nrUE.ubuntu index a395004cc1..3b55a64acd 100644 --- a/docker/Dockerfile.nrUE.ubuntu +++ b/docker/Dockerfile.nrUE.ubuntu @@ -119,6 +119,8 @@ RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so /usr/local/lib/liboai /usr/local/lib/libuhd.so.4.8.0 WORKDIR /opt/oai-nr-ue + +COPY --from=nr-ue-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=nr-ue-base /tini /tini CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c index 6ff535fb5b..e2c4144707 100644 --- a/executables/lte-softmodem.c +++ b/executables/lte-softmodem.c @@ -405,7 +405,6 @@ int main ( int argc, char **argv ) #if T_TRACER T_Config_Init(); #endif - //randominit (0); set_taus_seed (0); printf("configuring for RAU/RRU\n"); diff --git a/executables/lte-uesoftmodem.c b/executables/lte-uesoftmodem.c index f36bdde2b5..fc741ec300 100644 --- a/executables/lte-uesoftmodem.c +++ b/executables/lte-uesoftmodem.c @@ -492,7 +492,6 @@ int main( int argc, char **argv ) { #if T_TRACER T_Config_Init(); #endif - //randominit (0); set_taus_seed (0); cpuf=get_cpu_freq_GHz(); pthread_cond_init(&sync_cond,NULL); diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 4c72a2a120..bcbaa0e67f 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -119,10 +119,9 @@ static void tx_func(processingData_L1tx_t *info) pushNotifiedFIFO(&gNB->resp_L1, res); int tx_slot_type = nr_slot_select(cfg, frame_tx, slot_tx); - // TODO check for analog_beam_list is a workaround while no beam API for beam - // selection is implemented - if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx || IS_SOFTMODEM_RFSIM - || cfg->analog_beamforming_ve.analog_beam_list) { + // TODO check for analog_bf_vendor_ext set to 1 is a workaround while no beam API for beam selection is implemented + if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx + || IS_SOFTMODEM_RFSIM || cfg->analog_beamforming_ve.analog_bf_vendor_ext.value) { start_meas(&info->gNB->phy_proc_tx); phy_procedures_gNB_TX(info->gNB, &sched_response.DL_req, diff --git a/executables/nr-ru.c b/executables/nr-ru.c index ea43ecdff1..279b6f5142 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -247,7 +247,7 @@ int connect_rau(RU_t *ru) { void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx & 0xffffffff); - int offset = ru->nr_frame_parms->get_samples_slot_timestamp(slot,ru->nr_frame_parms,0); + int offset = get_samples_slot_timestamp(ru->nr_frame_parms, slot); void *buffs[ru->nb_tx]; for (int aid = 0; aid < ru->nb_tx; aid++) buffs[aid] = (void*)&ru->common.txdata[aid][offset]; @@ -260,15 +260,9 @@ void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { timestamp, buffs[0], buffs[1], - 10 * log10((double)signal_energy(buffs[0], ru->nr_frame_parms->get_samples_per_slot(slot, ru->nr_frame_parms))), + 10 * log10((double)signal_energy(buffs[0], get_samples_per_slot(slot, ru->nr_frame_parms))), (int)txmeas.tv_nsec); - ru->ifdevice.trx_write_func2(&ru->ifdevice, - timestamp, - buffs, - 0, - ru->nr_frame_parms->get_samples_per_slot(slot,ru->nr_frame_parms), - 0, - ru->nb_tx); + ru->ifdevice.trx_write_func2(&ru->ifdevice, timestamp, buffs, 0, get_samples_per_slot(slot, ru->nr_frame_parms), 0, ru->nb_tx); } // southbound IF4p5 fronthaul @@ -295,11 +289,11 @@ void fh_if5_south_in(RU_t *ru, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); start_meas(&ru->rx_fhaul); - ru->ifdevice.trx_read_func2(&ru->ifdevice, &proc->timestamp_rx, NULL, fp->get_samples_per_slot(*tti, fp)); + ru->ifdevice.trx_read_func2(&ru->ifdevice, &proc->timestamp_rx, NULL, get_samples_per_slot(*tti, fp)); if (proc->first_rx == 1) ru->ts_offset = proc->timestamp_rx; proc->frame_rx = ((proc->timestamp_rx - ru->ts_offset) / (fp->samples_per_subframe * 10)) & 1023; - proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx - ru->ts_offset, fp); + proc->tti_rx = get_slot_from_timestamp(proc->timestamp_rx - ru->ts_offset, fp); if (proc->first_rx == 0) { if (proc->tti_rx != *tti) { @@ -383,7 +377,7 @@ void fh_if4p5_south_in(RU_t *ru, //caculate timestamp_rx, timestamp_tx based on frame and subframe proc->tti_rx = sl; proc->frame_rx = f; - proc->timestamp_rx = (proc->frame_rx * fp->samples_per_subframe * 10) + fp->get_samples_slot_timestamp(proc->tti_rx, fp, 0); + proc->timestamp_rx = (proc->frame_rx * fp->samples_per_subframe * 10) + get_samples_slot_timestamp(fp, proc->tti_rx); // proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_subframe); proc->tti_tx = (sl+ru->sl_ahead)%fp->slots_per_frame; proc->frame_tx = (sl > (fp->slots_per_frame - 1 - (ru->sl_ahead))) ? (f + 1) & 1023 : f; @@ -528,7 +522,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { proc->frame_tx_unwrap += 1024; proc->timestamp_tx = - ((uint64_t)frame_tx + proc->frame_tx_unwrap) * fp->samples_per_subframe * 10 + fp->get_samples_slot_timestamp(slot_tx, fp, 0); + ((uint64_t)frame_tx + proc->frame_tx_unwrap) * fp->samples_per_subframe * 10 + get_samples_slot_timestamp(fp, slot_tx); LOG_D(PHY, "RU %d/%d TST %lu, frame %d, subframe %d\n", ru->idx, 0, proc->timestamp_tx, frame_tx, slot_tx); // dump VCD output for first RU in list @@ -566,14 +560,14 @@ static void rx_rf(RU_t *ru, int *frame, int *slot) RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; openair0_config_t *cfg = &ru->openair0_cfg; - uint32_t samples_per_slot = fp->get_samples_per_slot(*slot, fp); + uint32_t samples_per_slot = get_samples_per_slot(*slot, fp); AssertFatal(*slot < fp->slots_per_frame && *slot >= 0, "slot %d is illegal (%d)\n", *slot, fp->slots_per_frame); start_meas(&ru->rx_fhaul); int nb = ru->nb_rx * ru->num_beams_period; void *rxp[nb]; for (int i = 0; i < nb; i++) - rxp[i] = (void *)&ru->common.rxdata[i][fp->get_samples_slot_timestamp(*slot, fp, 0)]; + rxp[i] = (void *)&ru->common.rxdata[i][get_samples_slot_timestamp(fp, *slot)]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1); openair0_timestamp old_ts = proc->timestamp_rx; @@ -590,7 +584,7 @@ static void rx_rf(RU_t *ru, int *frame, int *slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n", samples_per_slot, rxs); if (proc->first_rx != 1) { - uint32_t samples_per_slot_prev = fp->get_samples_per_slot((*slot - 1) % fp->slots_per_frame, fp); + uint32_t samples_per_slot_prev = get_samples_per_slot((*slot - 1) % fp->slots_per_frame, fp); if (proc->timestamp_rx - old_ts != samples_per_slot_prev) { LOG_D(PHY, @@ -609,7 +603,7 @@ static void rx_rf(RU_t *ru, int *frame, int *slot) // in fact the following line is the same as long as the timestamp_rx is synchronized to GPS. proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023; - proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx,fp); + proc->tti_rx = get_slot_from_timestamp(proc->timestamp_rx, fp); // synchronize first reception to frame 0 subframe 0 LOG_D(PHY, "RU %d/%d TS %ld, GPS %f, SR %f, frame %d, slot %d.%d / %d\n", @@ -725,9 +719,9 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp) T_INT(frame), T_INT(slot), T_INT(0), - T_BUFFER(&ru->common.txdata[0][fp->get_samples_slot_timestamp(slot, fp, 0)], fp->get_samples_per_slot(slot, fp) * 4)); + T_BUFFER(&ru->common.txdata[0][get_samples_slot_timestamp(fp, slot)], get_samples_per_slot(slot, fp) * 4)); int sf_extension = 0; - int siglen=fp->get_samples_per_slot(slot,fp); + int siglen = get_samples_per_slot(slot, fp); radio_tx_burst_flag_t flags_burst = TX_BURST_INVALID; radio_tx_gpio_flag_t flags_gpio = 0; @@ -786,7 +780,7 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp) int nt = ru->nb_tx * ru->num_beams_period; void *txp[nt]; for (int i = 0; i < nt; i++) - txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot, fp, 0)] - sf_extension * sizeof(int32_t); + txp[i] = (void *)&ru->common.txdata[i][get_samples_slot_timestamp(fp, slot)] - sf_extension * sizeof(int32_t); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp + ru->ts_offset) & 0xffffffff); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1); @@ -902,6 +896,7 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_ } } + split7->prach_fftSize = prach_config->prach_sequence_length.value == 0 ? 10 : 8; // need to handle 5kHz cases better than this split7->fftSize = log2(fp->ofdm_symbol_size); // M-plane related parameters @@ -1176,7 +1171,7 @@ void *ru_thread(void *param) } proc->timestamp_tx = proc->timestamp_rx; for (int i = proc->tti_rx; i < proc->tti_rx + ru->sl_ahead; i++) - proc->timestamp_tx += fp->get_samples_per_slot(i % fp->slots_per_frame, fp); + proc->timestamp_tx += get_samples_per_slot(i % fp->slots_per_frame, fp); proc->tti_tx = (proc->tti_rx + ru->sl_ahead) % fp->slots_per_frame; proc->frame_tx = proc->tti_rx > proc->tti_tx ? (proc->frame_rx + 1) & 1023 : proc->frame_rx; LOG_D(PHY, diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 3e22659400..8a57b21af1 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -546,7 +546,6 @@ int main( int argc, char **argv ) { #if T_TRACER T_Config_Init(); #endif - //randominit (0); set_taus_seed (0); cpuf=get_cpu_freq_GHz(); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 5721b45f8d..c920a57b88 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -19,11 +19,11 @@ * contact@openairinterface.org */ +#include "PHY/defs_nr_common.h" #define _GNU_SOURCE // For pthread_setname_np #include #include #include "executables/nr-uesoftmodem.h" -#include "PHY/phy_extern_nr_ue.h" #include "PHY/INIT/nr_phy_init.h" #include "NR_MAC_UE/mac_proto.h" #include "RRC/NR_UE/rrc_proto.h" @@ -176,8 +176,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id) ue->dci_thres = 0; ue->target_Nid_cell = -1; - ue->ntn_config_message = CALLOC(1, sizeof(*ue->ntn_config_message)); - ue->ntn_config_message->update = false; + ue->nrUE_config.ntn_config.params_changed = false; // initialize all signal buffers init_nr_ue_signal(ue, nb_connected_gNB); @@ -257,7 +256,7 @@ static void UE_synch(void *arg) { + round((float)((ret.rx_offset << 1) % fp->samples_per_subframe) / fp->samples_per_slot0); if (get_nrUE_params()->cont_fo_comp) { - UE->freq_offset = freq_offset; + UE->freq_offset = freq_offset - UE->dl_Doppler_shift; } else { // rerun with new cell parameters and frequency-offset nr_rf_card_config_freq(cfg0, ul_carrier, dl_carrier, freq_offset); @@ -383,7 +382,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **tx openair0_timestamp writeTimestamp = proc->timestamp_tx; int writeBlockSize = rxtxD->writeBlockSize; // if writeBlockSize gets longer that slot size, fill with dummy - const int maxWriteBlockSize = fp->get_samples_per_slot(proc->nr_slot_tx, fp); + const int maxWriteBlockSize = get_samples_per_slot(proc->nr_slot_tx, fp); while (writeBlockSize > maxWriteBlockSize) { const int dummyBlockSize = min(writeBlockSize - maxWriteBlockSize, maxWriteBlockSize); int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, (void **)txp, dummyBlockSize, fp->nb_antennas_tx, flags); @@ -398,8 +397,15 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **tx double ul_freq_offset = -UE->freq_offset * ((double)fp->ul_CarrierFreq / (double)fp->dl_CarrierFreq); if (get_nrUE_params()->cont_fo_comp == 2) // different from LO frequency error compensation, Doppler UL pre-compensation has to be negative ul_freq_offset = -ul_freq_offset; + else if (get_nrUE_params()->cont_fo_comp == 3) // do not consider residual DL FO for UL pre-compensation at all + ul_freq_offset = 0; for (int i = 0; i < fp->nb_antennas_tx; i++) - nr_fo_compensation(ul_freq_offset, fp->samples_per_subframe, writeTimestamp, txp[i], txp[i], writeBlockSize); + nr_fo_compensation(UE->ul_Doppler_shift + ul_freq_offset, + fp->samples_per_subframe, + writeTimestamp, + txp[i], + txp[i], + writeBlockSize); } int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, (void **)txp, writeBlockSize, fp->nb_antennas_tx, flags); @@ -423,7 +429,7 @@ void processSlotTX(void *arg) NR_DL_FRAME_PARMS *fp = &UE->frame_parms; c16_t *txp[fp->nb_antennas_tx]; for (int i = 0; i < fp->nb_antennas_tx; i++) { - txp[i] = UE->common_vars.txData[i] + fp->get_samples_slot_timestamp(proc->nr_slot_tx, fp, 0); + txp[i] = UE->common_vars.txData[i] + get_samples_slot_timestamp(fp, proc->nr_slot_tx); } if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT) { @@ -434,8 +440,10 @@ void processSlotTX(void *arg) nr_sidelink_indication_t sl_indication = {.module_id = UE->Mod_id, .gNB_index = proc->gNB_id, .cc_id = UE->CC_id, + .hfn_tx = proc->hfn_tx, .frame_tx = proc->frame_tx, .slot_tx = proc->nr_slot_tx, + .hfn_rx = proc->hfn_rx, .frame_rx = proc->frame_rx, .slot_rx = proc->nr_slot_rx, .slot_type = SIDELINK_SLOT_TYPE_TX, @@ -506,6 +514,15 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE) uint64_t dl_CarrierFreq = get_carrier_frequency(fp->N_RB_DL, fp->numerology_index, cfg->dl_frequency); uint64_t ul_CarrierFreq = get_carrier_frequency(fp->N_RB_UL, fp->numerology_index, cfg->uplink_frequency); if (dl_CarrierFreq != fp->dl_CarrierFreq || ul_CarrierFreq != fp->ul_CarrierFreq) { + LOG_I(NR_PHY, + "[UE %d] RF frequency change: dl %lu->%lu Hz, ul %lu->%lu Hz (from dl_frequency=%u kHz, target_Nid_cell=%d)\n", + UE->Mod_id, + fp->dl_CarrierFreq, + dl_CarrierFreq, + fp->ul_CarrierFreq, + ul_CarrierFreq, + cfg->dl_frequency, + UE->target_Nid_cell); fp->dl_CarrierFreq = dl_CarrierFreq; fp->ul_CarrierFreq = ul_CarrierFreq; nr_rf_card_config_freq(&UE->openair0_cfg[UE->rf_map.card], ul_CarrierFreq, dl_CarrierFreq, 0); @@ -513,6 +530,12 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE) init_symbol_rotation(fp); } + // Apply Doppler based on NTN-Config for target cell + if (UE->nrUE_config.ntn_config.is_targetcell) + apply_ntn_timing_advance_and_doppler(UE, fp, -1); + // Apply NTN DL Doppler as initial FO + UE->initial_fo = UE->dl_Doppler_shift; + /* Clearing UE harq while DL actors are active causes race condition. So we let the current execution to complete here.*/ for (int i = 0; i < get_nrUE_params()->num_dl_actors; i++) { @@ -654,24 +677,25 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, int duration_r void *rxp[NB_ANTENNAS_RX]; if (toTrash) for (int i = 0; i < fp->nb_antennas_rx; i++) - rxp[i] = malloc16(fp->get_samples_per_slot(0, fp) * 4); + rxp[i] = malloc16(get_samples_per_slot(0, fp) * 4); for (int x = 0; x < num_frames * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; x++) { // two frames for initial sync for (int slot = 0; slot < fp->slots_per_subframe; slot++) { if (!toTrash) for (int i = 0; i < fp->nb_antennas_rx; i++) - rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) - + 4 * ((x * fp->samples_per_subframe) + fp->get_samples_slot_timestamp(slot, fp, 0)); + rxp[i] = + ((void *)&UE->common_vars.rxdata[i][0]) + 4 * ((x * fp->samples_per_subframe) + get_samples_slot_timestamp(fp, slot)); - int read_block_size = fp->get_samples_per_slot(slot, fp); + int read_block_size = get_samples_per_slot(slot, fp); int tmp = UE->rfdevice.trx_read_func(&UE->rfdevice, timestamp, rxp, read_block_size, fp->nb_antennas_rx); UEscopeCopy(UE, ueTimeDomainSamplesBeforeSync, rxp[0], sizeof(c16_t), 1, read_block_size, 0); AssertFatal(read_block_size == tmp, ""); if (IS_SOFTMODEM_RFSIM) { + int ta = UE->timing_advance + UE->timing_advance_ntn; const openair0_timestamp writeTimestamp = - *timestamp + fp->get_samples_slot_timestamp(slot, fp, duration_rx_to_tx) - UE->N_TA_offset - UE->timing_advance; - dummyWrite(UE, writeTimestamp, fp->get_samples_per_slot(slot, fp)); + *timestamp + get_samples_slot_duration(fp, slot, duration_rx_to_tx) - UE->N_TA_offset - ta; + dummyWrite(UE, writeTimestamp, get_samples_per_slot(slot, fp)); } } } @@ -692,12 +716,13 @@ static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, int d int slot = 0; int size = rx_offset; while (size > 0) { - const int unitTransfer = min(fp->get_samples_per_slot(slot, fp), size); + const int unitTransfer = min(get_samples_per_slot(slot, fp), size); const int res = UE->rfdevice.trx_read_func(&UE->rfdevice, timestamp, (void **)UE->common_vars.rxdata, unitTransfer, fp->nb_antennas_rx); DevAssert(unitTransfer == res); if (IS_SOFTMODEM_RFSIM) { + int ta = UE->timing_advance + UE->timing_advance_ntn; const openair0_timestamp writeTimestamp = - *timestamp + fp->get_samples_slot_timestamp(slot, fp, duration_rx_to_tx) - UE->N_TA_offset - UE->timing_advance; + *timestamp + get_samples_slot_duration(fp, slot, duration_rx_to_tx) - UE->N_TA_offset - ta; dummyWrite(UE, writeTimestamp, unitTransfer); } slot = (slot + 1) % fp->slots_per_subframe; @@ -706,73 +731,17 @@ static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, int d } static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) { - if (fp->numerology_index == 0) - return fp->nb_prefix_samples0 + fp->ofdm_symbol_size; - int num_samples = (slot%(fp->slots_per_subframe/2)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0; - num_samples += fp->ofdm_symbol_size; - return num_samples; + return get_samples_symbol_duration(fp, slot, 0, 1); } static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) { - int rem_samples = fp->get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp); + int rem_samples = get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp); int next_slot_first_symbol = 0; if (slot < (fp->slots_per_frame-1)) next_slot_first_symbol = get_firstSymSamp(slot+1, fp); return rem_samples + next_slot_first_symbol; } -static inline void apply_ntn_config(PHY_VARS_NR_UE *UE, - NR_DL_FRAME_PARMS *fp, - int frame_rx, - int slot_rx, - int *duration_rx_to_tx, - int *timing_advance, - int *ntn_koffset) -{ - if (UE->ntn_config_message->update) { - UE->ntn_config_message->update = false; - - const int mu = fp->numerology_index; - const int koffset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset; - - *duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX + (koffset << mu); - if (koffset > *ntn_koffset) - *timing_advance += fp->get_samples_slot_timestamp(slot_rx, fp, (koffset - *ntn_koffset) << mu); - else if (koffset < *ntn_koffset) - *timing_advance -= fp->get_samples_slot_timestamp(slot_rx, fp, (*ntn_koffset - koffset) << mu); - *ntn_koffset = koffset; - - const int abs_subframe_tx = 10 * frame_rx + ((slot_rx + *duration_rx_to_tx) >> mu); - const int abs_subframe_epoch = - 10 * UE->ntn_config_message->ntn_config_params.epoch_sfn + UE->ntn_config_message->ntn_config_params.epoch_subframe; - int ms_since_epoch = abs_subframe_tx - abs_subframe_epoch; - // cope with sfn wrap-around - // this currently limits us to epoch times that are not more than 5.12 seconds in the future (allowed are up to 10.24 seconds) - // and ntn-UlSyncValidityDuration < 5.12 seconds (allowed are up to 900 seconds) - // TODO: fix this limitation by introducing the hyper frame number HFN - if (ms_since_epoch < -5120) - ms_since_epoch += 10240; - else if (ms_since_epoch > 5120) - ms_since_epoch -= 10240; - - const double total_ta_ms = UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms; - const double total_ta_drift = UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_drift; // µs/s - const double total_ta_drift_variant = UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_drift_variant; // µs/s² - UE->timing_advance = fp->samples_per_subframe * (total_ta_ms + (total_ta_drift / 1000.0) * (ms_since_epoch / 1000.0) + (total_ta_drift_variant / 1000.0) * (ms_since_epoch / 1000.0) * (ms_since_epoch / 1000.0)); - - LOG_I(PHY, - "k_offset = %d ms (%d slots), total_ta_ms = %f ms, total_ta_drift = %f µs/s, total_ta_drift_variant = %f µs/s², ms_since_epoch = %d ms, computed " - "timing_advance = %d samples\n", - *ntn_koffset, - *ntn_koffset << mu, - total_ta_ms, - total_ta_drift, - total_ta_drift_variant, - ms_since_epoch, - UE->timing_advance); - } -} - void *UE_thread(void *arg) { //this thread should be over the processing thread to keep in real time @@ -805,11 +774,17 @@ void *UE_thread(void *arg) notifiedFIFO_t freeBlocks; initNotifiedFIFO_nothreadSafe(&freeBlocks); - double ntn_init_time_drift = get_nrUE_params()->ntn_init_time_drift; - int ntn_koffset = 0; + const double ntn_init_time_drift = get_nrUE_params()->ntn_init_time_drift; + if (get_nrUE_params()->time_sync_I) + // ntn_init_time_drift is in µs/s, max_pos_acc * time_sync_I is in samples/frame + UE->max_pos_acc = ntn_init_time_drift * 1e-6 * fp->samples_per_frame / get_nrUE_params()->time_sync_I; + else + UE->max_pos_acc = 0; + bool ntn_targetcell = false; + int ntn_koffset = 0; int duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX; - int timing_advance = UE->timing_advance; + int timing_advance = UE->timing_advance + UE->timing_advance_ntn; UE->N_TA_offset = determine_N_TA_offset(UE); NR_UE_MAC_INST_t *mac = get_mac_inst(UE->Mod_id); @@ -903,10 +878,6 @@ void *UE_thread(void *arg) syncMsg->UE = UE; memset(&syncMsg->proc, 0, sizeof(syncMsg->proc)); pushNotifiedFIFO(&UE->sync_actor.fifo, Msg); - if (ntn_koffset == 0) { // reset timing_advance for TN - timing_advance = 0; - UE->timing_advance = 0; - } trashed_frames = 0; syncRunning = true; continue; @@ -916,13 +887,8 @@ void *UE_thread(void *arg) stream_status = STREAM_STATUS_SYNCING; syncInFrame(UE, &sync_timestamp, duration_rx_to_tx, intialSyncOffset); openair0_write_reorder_clear_context(&UE->rfdevice); - if (get_nrUE_params()->time_sync_I) - // ntn_init_time_drift is in µs/s, max_pos_acc * time_sync_I is in samples/frame - UE->max_pos_acc = ntn_init_time_drift * 1e-6 * fp->samples_per_frame / get_nrUE_params()->time_sync_I; - else - UE->max_pos_acc = 0; shiftForNextFrame = -(UE->init_sync_frame + trashed_frames + 2) * UE->max_pos_acc * get_nrUE_params()->time_sync_I; // compensate for the time drift that happened during initial sync - LOG_D(PHY, "max_pos_acc = %d, shiftForNextFrame = %d\n", UE->max_pos_acc, shiftForNextFrame); + LOG_I(PHY, "max_pos_acc = %d, shiftForNextFrame = %d\n", UE->max_pos_acc, shiftForNextFrame); // read in first symbol AssertFatal(fp->ofdm_symbol_size + fp->nb_prefix_samples0 == UE->rfdevice.trx_read_func(&UE->rfdevice, @@ -934,12 +900,35 @@ void *UE_thread(void *arg) // we have the decoded frame index in the return of the synch process // and we shifted above to the first slot of next frame decoded_frame_rx = (decoded_frame_rx + 1) % MAX_FRAME_NUMBER; + const int prev_frame_rx = (absolute_slot / nb_slot_frame) % MAX_FRAME_NUMBER; + const int prev_hfn_rx = (absolute_slot / nb_slot_frame) / MAX_FRAME_NUMBER; + int decoded_hfn_rx = prev_hfn_rx; + if (decoded_frame_rx <= prev_frame_rx) + decoded_hfn_rx++; // we do ++ first in the regular processing, so it will be begin of frame; - absolute_slot = decoded_frame_rx * nb_slot_frame - 1; + absolute_slot = (decoded_hfn_rx * MAX_FRAME_NUMBER + decoded_frame_rx) * nb_slot_frame - 1; if (UE->sl_mode == 2) { // Set to the slot where the SL-SSB was decoded absolute_slot += UE->SL_UE_PHY_PARAMS.sync_params.slot_offset; } + // With the correct frame and slot numbers, we can now fix the UL timing + fix_ntn_epoch_hfn(UE, decoded_hfn_rx, decoded_frame_rx); + if (UE->nrUE_config.ntn_config.params_changed) { + apply_ntn_config(UE, + fp, + decoded_hfn_rx, + decoded_frame_rx, + 0, + &duration_rx_to_tx, + &timing_advance, + &ntn_koffset, + &ntn_targetcell); + } else { + const int abs_subframe_tx = (absolute_slot + 1 + duration_rx_to_tx) / fp->slots_per_subframe; + apply_ntn_timing_advance_and_doppler(UE, fp, abs_subframe_tx); + ntn_targetcell = false; + } + UE->timing_advance = 0; // We have resynchronized, maybe after RF loss so we need to purge any existing context memset(tx_wait_for_dlsch, 0, sizeof(tx_wait_for_dlsch)); for (int i = 0; i < NUM_PROCESS_SLOT_TX_BARRIERS; i++) { @@ -968,6 +957,8 @@ void *UE_thread(void *arg) 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.hfn_rx = (absolute_slot / nb_slot_frame) / MAX_FRAME_NUMBER; + curMsg.proc.hfn_tx = ((absolute_slot + duration_rx_to_tx) / nb_slot_frame) / MAX_FRAME_NUMBER; if (UE->received_config_request) { if (UE->sl_mode) { curMsg.proc.rx_slot_type = sl_nr_ue_slot_select(sl_cfg, curMsg.proc.nr_slot_rx, TDD); @@ -984,18 +975,25 @@ void *UE_thread(void *arg) int firstSymSamp = get_firstSymSamp(slot_nr, fp); for (int i = 0; i < fp->nb_antennas_rx; i++) - rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp + fp->get_samples_slot_timestamp(slot_nr, fp, 0)]; + rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp + get_samples_slot_timestamp(fp, slot_nr)]; int iq_shift_to_apply = 0; if (slot_nr == nb_slot_frame - 1) { // we shift of half of measured drift, at each beginning of frame for both rx and tx iq_shift_to_apply = shiftForNextFrame; - // TODO: remove this autonomous TA and use up-to-date values of ta-Common, ta-CommonDrift and ta-CommonDriftVariant from received SIB19 instead - if (get_nrUE_params()->autonomous_ta) - UE->timing_advance -= 2 * shiftForNextFrame; + // autonomous timing advance calculation, which does not use SIB19 information + if (ntn_koffset && get_nrUE_params()->autonomous_ta) + UE->timing_advance_ntn -= 2 * shiftForNextFrame; shiftForNextFrame = -round(UE->max_pos_acc * get_nrUE_params()->time_sync_I); } + // Calculate new TA based on SIB19 information for each subframe in NTN mode, if "autonomous_ta" is not enabled + if (ntn_koffset && !ntn_targetcell && !get_nrUE_params()->autonomous_ta + && (absolute_slot + duration_rx_to_tx) % fp->slots_per_subframe == 0) { + const int abs_subframe_tx = (absolute_slot + duration_rx_to_tx) / fp->slots_per_subframe; + apply_ntn_timing_advance_and_doppler(UE, fp, abs_subframe_tx); + } + const int readBlockSize = get_readBlockSize(slot_nr, fp) - iq_shift_to_apply; openair0_timestamp rx_timestamp; int tmp = UE->rfdevice.trx_read_func(&UE->rfdevice, &rx_timestamp, rxp, readBlockSize, fp->nb_antennas_rx); @@ -1025,8 +1023,8 @@ void *UE_thread(void *arg) } // use previous timing_advance value to compute writeTimestamp - const openair0_timestamp writeTimestamp = rx_timestamp + fp->get_samples_slot_timestamp(slot_nr, fp, duration_rx_to_tx) - - firstSymSamp - UE->N_TA_offset - timing_advance; + const openair0_timestamp writeTimestamp = + rx_timestamp + get_samples_slot_duration(fp, slot_nr, duration_rx_to_tx) - firstSymSamp - UE->N_TA_offset - timing_advance; // Calculate TX deadline, approximately 1 symbol before the first sample should be written const uint64_t samples_diff = writeTimestamp - rx_timestamp - fp->ofdm_symbol_size; @@ -1034,8 +1032,8 @@ void *UE_thread(void *arg) const uint64_t absolute_deadline_us = current_time.tv_sec * 1e6 + current_time.tv_nsec / 1e3 + deadline_us; // but use current UE->timing_advance value to compute writeBlockSize - int writeBlockSize = fp->get_samples_per_slot((slot_nr + duration_rx_to_tx) % nb_slot_frame, fp) - iq_shift_to_apply; - int new_timing_advance = UE->timing_advance; + int writeBlockSize = get_samples_per_slot((slot_nr + duration_rx_to_tx) % nb_slot_frame, fp) - iq_shift_to_apply; + int new_timing_advance = UE->timing_advance + UE->timing_advance_ntn; if (new_timing_advance != timing_advance) { writeBlockSize -= new_timing_advance - timing_advance; timing_advance = new_timing_advance; @@ -1046,9 +1044,14 @@ void *UE_thread(void *arg) writeBlockSize -= new_N_TA_offset - UE->N_TA_offset; UE->N_TA_offset = new_N_TA_offset; } + if (writeBlockSize < 0) { + timing_advance += writeBlockSize - 1; + LOG_I(PHY, "writeBlockSize is %d, setting it to 1 and changing timing_advance to %d\n", writeBlockSize, timing_advance); + writeBlockSize = 1; + } if (curMsg.proc.nr_slot_rx == 0) - nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.frame_rx, curMsg.proc.gNB_id); + nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.hfn_rx, curMsg.proc.frame_rx, curMsg.proc.gNB_id); // RX slot processing. We launch and forget. notifiedFIFO_elt_t *newRx = newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), curMsg.proc.nr_slot_tx, NULL, UE_dl_processing); @@ -1064,7 +1067,15 @@ void *UE_thread(void *arg) } // apply new NTN timing information - apply_ntn_config(UE, fp, curMsg.proc.frame_rx, curMsg.proc.nr_slot_rx, &duration_rx_to_tx, &timing_advance, &ntn_koffset); + apply_ntn_config(UE, + fp, + curMsg.proc.hfn_rx, + curMsg.proc.frame_rx, + curMsg.proc.nr_slot_rx, + &duration_rx_to_tx, + &timing_advance, + &ntn_koffset, + &ntn_targetcell); // Start TX slot processing here. It runs in parallel with RX slot processing // in current code, DURATION_RX_TO_TX constant is the limit to get UL data to encode from a RX slot @@ -1078,7 +1089,7 @@ void *UE_thread(void *arg) curMsgTx->absolute_deadline_us = absolute_deadline_us; int slot = curMsgTx->proc.nr_slot_tx; - int slot_and_frame = slot + curMsgTx->proc.frame_tx * UE->frame_parms.slots_per_frame; + int slot_and_frame = slot + curMsgTx->proc.frame_tx * nb_slot_frame; int next_tx_slot_and_frame = absolute_slot + duration_rx_to_tx + 1; int wait_for_prev_slot = stream_status == STREAM_STATUS_SYNCED ? 1 : 0; diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index ca6c48dbef..f1cc659cae 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -340,7 +340,6 @@ int main(int argc, char **argv) T_Config_Init(); #endif initTpool(get_softmodem_params()->threadPoolConfig, &(nrUE_params.Tpool), cpumeas(CPUMEAS_GETSTATE)); - //randominit (0); set_taus_seed (0); if (!has_cap_sys_nice()) diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index df13e2e02e..f14594b0dd 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -21,7 +21,7 @@ extern uint16_t ue_id_g; #define CONFIG_HLP_INITIAL_FO "Initially compensated DL frequency offset (e.g. known Doppler shift in NTN LEO scenario)\n" #define CONFIG_HLP_FREQ_SYNC_P "coefficient for Proportional part of continuous frequency offset compensation PI controller\n" #define CONFIG_HLP_FREQ_SYNC_I "coefficient for Integrating part of continuous frequency offset compensation PI controller\n" -#define CONFIG_HLP_CONT_FO_COMP "Enable continuous frequency offset (FO) estimation and compensation and specify main FO source (1 = local oscillator, 2 = Doppler shift)\n" +#define CONFIG_HLP_CONT_FO_COMP "Enable continuous frequency offset (FO) estimation and (pre-)compensation and specify main FO source (1 = local oscillator, 2 = Doppler shift, 3 = Don't consider residual DL FO in UL FO pre-compensation)\n" #define CONFIG_HLP_AGC "Rx Gain control used for UE\n" #define CONFIG_HLP_NUM_UL_ACTORS "Number of UL actors to use. Set to 0 to disable UL actor framework and do processing inline\n" #define CONFIG_HLP_NUM_DL_ACTORS "Number of DL actors to use. Set to 0 to disable DL actor framework and do processing inline\n" diff --git a/executables/position_interface.c b/executables/position_interface.c index be37515096..fa28e7e884 100644 --- a/executables/position_interface.c +++ b/executables/position_interface.c @@ -20,6 +20,7 @@ */ #include "position_interface.h" +#include "executables/nr-uesoftmodem.h" static void read_position_coordinates(char *sectionName, position_t *position) { diff --git a/executables/position_interface.h b/executables/position_interface.h index 8ef0b3144b..af8c581712 100644 --- a/executables/position_interface.h +++ b/executables/position_interface.h @@ -22,11 +22,6 @@ #ifndef __POSITION_INTERFACE__H__ #define __POSITION_INTERFACE__H__ -#include -#include -#include "PHY/defs_nr_UE.h" -#include "executables/nr-uesoftmodem.h" - /* position configuration parameters name */ #define CONFIG_STRING_POSITION_X "x" #define CONFIG_STRING_POSITION_Y "y" diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 7a6e4f7657..8b07bea297 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -2315,7 +2315,7 @@ void handle_nr_slot_ind(uint16_t sfn, uint16_t slot, NR_Sched_Rsp_t *sched_resp) #ifndef ENABLE_WLS int slot_ahead = 2 << mu; #else - int slot_ahead = 1; + int slot_ahead = 1 << mu; #endif uint16_t sfn_tx = sfn; uint16_t slot_tx = slot; diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c index c3e36d9999..9bbda9d519 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c @@ -1229,33 +1229,6 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e // only increase if it was set numTLVs += pNfapiMsg->analog_beamforming_ve.analog_bf_vendor_ext.tl.tag == NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG; - AssertFatal(pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext.tl.tag == 0, - "Total num beams Vendor extension shouldn't be set!"); - // The call to pack the TLV would be the same as any other TLV, it is only packed if the tag is set, - // so, it's safe to add the call to pack_nr_tlv even if it is not always set - retval &= pack_nr_tlv(NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG, - &(pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext), - ppWritePackedMsg, - end, - &pack_uint8_tlv_value); - // only increase if it was set - numTLVs += - pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext.tl.tag == NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG; - - for (int beam = 0; beam < pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext.value; beam++) { - AssertFatal(pNfapiMsg->analog_beamforming_ve.analog_beam_list[beam].tl.tag == 0, - "Analog beams list Vendor extension shouldn't be set!"); - // The call to pack the TLV would be the same as any other TLV, it is only packed if the tag is set, - // so, it's safe to add the call to pack_nr_tlv even if it is not always set - retval &= pack_nr_tlv(NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG, - &(pNfapiMsg->analog_beamforming_ve.analog_beam_list[beam]), - ppWritePackedMsg, - end, - &pack_uint8_tlv_value); - // only increase if it was set - numTLVs += pNfapiMsg->analog_beamforming_ve.analog_bf_vendor_ext.tl.tag == NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG; - } - pNfapiMsg->num_tlv = numTLVs; retval &= push8(pNfapiMsg->num_tlv, &pNumTLVFields, end); return retval; @@ -1357,7 +1330,6 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void * int tdd_periodicity_idx = 0; int symbol_per_slot_idx = 0; #endif - int beam_ve_idx = 0; nfapi_nr_config_request_scf_t *pNfapiMsg = (nfapi_nr_config_request_scf_t *)msg; // unpack TLVs @@ -1417,10 +1389,12 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void * {NFAPI_NR_CONFIG_TDD_TABLE, NULL, &unpack_nr_tdd_table_10_04}, #endif #endif - {NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG, &(pNfapiMsg->analog_beamforming_ve.num_beams_period_vendor_ext), &unpack_uint8_tlv_value}, - {NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG, &(pNfapiMsg->analog_beamforming_ve.analog_bf_vendor_ext), &unpack_uint8_tlv_value}, - {NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG, &(pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext), &unpack_uint8_tlv_value}, - {NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG, NULL, &unpack_uint8_tlv_value}, + {NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG, + &(pNfapiMsg->analog_beamforming_ve.num_beams_period_vendor_ext), + &unpack_uint8_tlv_value}, + {NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG, + &(pNfapiMsg->analog_beamforming_ve.analog_bf_vendor_ext), + &unpack_uint8_tlv_value}, {NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG, &(pNfapiMsg->measurement_config.rssi_measurement), &unpack_uint8_tlv_value}, {NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG, NULL, &unpack_dbt_table_tlv_value}, {NFAPI_NR_CONFIG_PRECODING_TABLE_V6_TAG, NULL, &unpack_pm_table_tlv_value}, @@ -1463,21 +1437,6 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void * } int result = 0; switch (generic_tl.tag) { - case NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG: - pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext.tl.tag = generic_tl.tag; - pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext.tl.length = generic_tl.length; - result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext, ppReadPackedMsg, end); - pNfapiMsg->analog_beamforming_ve.analog_beam_list = (nfapi_uint8_tlv_t *)malloc( - pNfapiMsg->analog_beamforming_ve.total_num_beams_vendor_ext.value * sizeof(nfapi_uint8_tlv_t)); - beam_ve_idx = 0; - break; - case NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG: - unpack_fns[idx].tlv = &pNfapiMsg->analog_beamforming_ve.analog_beam_list[beam_ve_idx]; - pNfapiMsg->analog_beamforming_ve.analog_beam_list[beam_ve_idx].tl.tag = generic_tl.tag; - pNfapiMsg->analog_beamforming_ve.analog_beam_list[beam_ve_idx].tl.length = generic_tl.length; - result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->analog_beamforming_ve.analog_beam_list[beam_ve_idx], ppReadPackedMsg, end); - beam_ve_idx ++; - break; case NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG: unpack_fns[idx].tlv = &generic_tl; result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->dbt_config, ppReadPackedMsg, end); diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c index 5d1d0ba4e8..1ef65b664c 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c @@ -315,12 +315,6 @@ bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const EQ_TLV(unpacked_req->analog_beamforming_ve.analog_bf_vendor_ext, req->analog_beamforming_ve.analog_bf_vendor_ext); - EQ_TLV(unpacked_req->analog_beamforming_ve.total_num_beams_vendor_ext, req->analog_beamforming_ve.total_num_beams_vendor_ext); - - for (int i = 0; i < unpacked_req->analog_beamforming_ve.total_num_beams_vendor_ext.value; ++i) { - EQ_TLV(unpacked_req->analog_beamforming_ve.analog_beam_list[i], req->analog_beamforming_ve.analog_beam_list[i]); - } - return true; } @@ -464,10 +458,6 @@ void free_config_request(nfapi_nr_config_request_scf_t *msg) free(msg->dbt_config.dig_beam_list); free(msg->pmi_list.pmi_pdu); - - if (msg->analog_beamforming_ve.analog_beam_list) { - free(msg->analog_beamforming_ve.analog_beam_list); - } } void free_config_response(nfapi_nr_config_response_scf_t *msg) @@ -895,17 +885,6 @@ void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_conf COPY_TLV(dst->analog_beamforming_ve.num_beams_period_vendor_ext, src->analog_beamforming_ve.num_beams_period_vendor_ext); COPY_TLV(dst->analog_beamforming_ve.analog_bf_vendor_ext, src->analog_beamforming_ve.analog_bf_vendor_ext); - - COPY_TLV(dst->analog_beamforming_ve.total_num_beams_vendor_ext, src->analog_beamforming_ve.total_num_beams_vendor_ext); - - if (dst->analog_beamforming_ve.total_num_beams_vendor_ext.value > 0) { - dst->analog_beamforming_ve.analog_beam_list = (nfapi_uint8_tlv_t *)malloc( - dst->analog_beamforming_ve.total_num_beams_vendor_ext.value * sizeof(nfapi_uint8_tlv_t)); - for (int i = 0; i < src->analog_beamforming_ve.total_num_beams_vendor_ext.value; ++i) { - COPY_TLV(dst->analog_beamforming_ve.analog_beam_list[i], src->analog_beamforming_ve.analog_beam_list[i]); - } - } - } void copy_config_response(const nfapi_nr_config_response_scf_t *src, nfapi_nr_config_response_scf_t *dst) diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c index aa90d3b4b9..3315ee2a4c 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c @@ -236,6 +236,12 @@ bool fapi_nr_p7_message_unpack(void *pMessageBuf, return true; } +#ifndef ENABLE_AERIAL +#define PARSE_BEAMID(a) (a) +#else +#define PARSE_BEAMID(a) ((a) & 0x7fff) +#endif + static uint8_t pack_nr_tx_beamforming_pdu(const nfapi_nr_tx_precoding_and_beamforming_t *beamforming_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) @@ -249,7 +255,9 @@ static uint8_t pack_nr_tx_beamforming_pdu(const nfapi_nr_tx_precoding_and_beamfo return 0; } for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interfaces; digBFInterface++) { - if (!push16(beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end)) { + if (!push16(PARSE_BEAMID(beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx), + ppWritePackedMsg, + end)) { return 0; } } @@ -715,7 +723,9 @@ static uint8_t pack_nr_rx_beamforming_pdu(const nfapi_nr_ul_beamforming_t *beamf } for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) { for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interface; digBFInterface++) { - if (!push16(beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end)) { + if (!push16(PARSE_BEAMID(beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx), + ppWritePackedMsg, + end)) { return 0; } } @@ -1400,7 +1410,7 @@ static uint8_t pack_ul_dci_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, return 0; } for (int digInt = 0; digInt < beamforming->dig_bf_interfaces; digInt++) { - if (!push16(beamforming->prgs_list[prg].dig_bf_interface_list[digInt].beam_idx, ppWritePackedMsg, end)) { + if (!push16(PARSE_BEAMID(beamforming->prgs_list[prg].dig_bf_interface_list[digInt].beam_idx), ppWritePackedMsg, end)) { return 0; } } diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h index 57292ecee5..04bb77f5de 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h @@ -51,9 +51,7 @@ #define FAPI_NR_DL_CONFIG_TYPE_CSI_RS 0x06 #define FAPI_NR_DL_CONFIG_TYPE_CSI_IM 0x07 #define FAPI_NR_CONFIG_TA_COMMAND 0x08 -#define FAPI_NR_DL_NTN_CONFIG_PARAMS 0x09 -#define FAPI_NR_DL_CONFIG_TYPES 0x09 - +#define FAPI_NR_DL_CONFIG_TYPES 0x08 #define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01 #define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index faebaffc6f..dd6b8135ab 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 @@ -24,6 +24,7 @@ #include "PHY/impl_defs_top.h" #include "PHY/impl_defs_nr.h" #include "common/utils/nr/nr_common.h" +#include "executables/position_interface.h" #define NFAPI_UE_MAX_NUM_CB 8 #define NFAPI_MAX_NUM_UL_PDU 255 @@ -72,6 +73,7 @@ typedef struct { typedef struct { /// frequency_domain_resource; uint8_t frequency_domain_resource[6]; + uint32_t rb_offset; uint8_t StartSymbolIndex; uint16_t StartSymbolBitmap; uint8_t duration; @@ -562,19 +564,34 @@ typedef struct { } fapi_nr_ta_command_pdu; typedef struct { + int epoch_hfn; int epoch_sfn; int epoch_subframe; + // orbital angular velocity in rad/ms + double omega; + // satellite position vector at epoch time + position_t pos_sat_0; + // satellite position vector at 90° orbit + position_t pos_sat_90; + // satellite velocity vector at epoch time + position_t vel_sat_0; + // satellite velocity vector at 90° orbit + position_t vel_sat_90; + + // N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms) + double N_common_ta_adj; + // drift rate of common ta in µs/s + double N_common_ta_drift; + // change rate of common ta drift in µs/s² + double N_common_ta_drift_variant; + // cell scheduling offset expressed in terms of 15kHz SCS long cell_specific_k_offset; - // ntn_total_time_advance_ms represents the complete round-trip-time between gNB and UE via SAT - double ntn_total_time_advance_ms; - // drift rate of ntn_total_time_advance_ms in µs/s - double ntn_total_time_advance_drift; - // change rate of ntn_total_time_advance_ms drift in µs/s² - double ntn_total_time_advance_drift_variant; -} fapi_nr_dl_ntn_config_command_pdu; + bool is_targetcell; + bool params_changed; +} fapi_nr_ntn_config_t; typedef struct { uint8_t pdu_type; @@ -584,7 +601,6 @@ typedef struct { fapi_nr_dl_config_csirs_pdu csirs_config_pdu; fapi_nr_dl_config_csiim_pdu csiim_config_pdu; fapi_nr_ta_command_pdu ta_command_pdu; - fapi_nr_dl_ntn_config_command_pdu ntn_config_command_pdu; }; } fapi_nr_dl_config_request_pdu_t; @@ -697,7 +713,6 @@ typedef struct uint8_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B uint8_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8 fapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list; - uint8_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16 uint8_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled uint8_t root_seq_computed; // flag set and used only in PHY to indicate if table is computed with this config @@ -717,6 +732,7 @@ typedef struct { fapi_nr_ssb_table_t ssb_table; fapi_nr_tdd_table_t tdd_table; fapi_nr_prach_config_t prach_config; + fapi_nr_ntn_config_t ntn_config; } fapi_nr_config_request_t; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h index 683de59c59..2e74fdc800 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -31,9 +31,6 @@ #define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x0120 #define NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG 0xA000 #define NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG 0xA001 -#define NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG 0xA002 -#define NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG 0xA003 - typedef struct { uint16_t phy_id; 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 12cf081fdc..10e6b7c14a 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 @@ -512,8 +512,6 @@ typedef struct { typedef struct { nfapi_uint8_tlv_t num_beams_period_vendor_ext; nfapi_uint8_tlv_t analog_bf_vendor_ext; - nfapi_uint8_tlv_t total_num_beams_vendor_ext; - nfapi_uint8_tlv_t *analog_beam_list; } nfapi_nr_analog_beamforming_ve_t; // ERROR enums diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c index af02ef7a4e..d2006170f0 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c @@ -268,8 +268,8 @@ int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_ pnf_p7_t* _this = (pnf_p7_t*)(config); AssertFatal(_this->_public.send_p7_msg, "Function pointer must be configured|"); - int ret = _this->_public.send_p7_msg(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t)); - if (ret == 0) { + bool ret = _this->_public.send_p7_msg(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t)); + if (ret) { for (int i = 0; i < ind->number_of_pdus; ++i) _this->nr_stats.ul.bytes += ind->pdu_list[i].pdu_length; } diff --git a/nfapi/tests/p5/nr_fapi_config_request_test.c b/nfapi/tests/p5/nr_fapi_config_request_test.c index 5a80a89f3d..ed57a64d62 100644 --- a/nfapi/tests/p5/nr_fapi_config_request_test.c +++ b/nfapi/tests/p5/nr_fapi_config_request_test.c @@ -285,12 +285,10 @@ static void fill_config_request_tlv_tdd_rand(nfapi_nr_config_request_scf_t *nfap FILL_TLV(nfapi_resp->nfapi_config.timing_info_period, NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, rand8()); nfapi_resp->num_tlv++; -/* - // TODO: Uncomment this block when ready to enable the pack of the following VE TLVs in nr_fapi_p5.c - // NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG - // NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG - // NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG - // NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG + /* + // TODO: Uncomment this block when ready to enable the pack of the following VE TLVs in nr_fapi_p5.c + // NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG + // NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG FILL_TLV(nfapi_resp->analog_beamforming_ve.num_beams_period_vendor_ext, NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG, rand8()); @@ -298,20 +296,7 @@ static void fill_config_request_tlv_tdd_rand(nfapi_nr_config_request_scf_t *nfap FILL_TLV(nfapi_resp->analog_beamforming_ve.analog_bf_vendor_ext, NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG, rand8()); nfapi_resp->num_tlv++; - - FILL_TLV(nfapi_resp->analog_beamforming_ve.total_num_beams_vendor_ext, - NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG, - rand8()); - nfapi_resp->num_tlv++; - - if (nfapi_resp->analog_beamforming_ve.total_num_beams_vendor_ext.value > 0) { - nfapi_resp->analog_beamforming_ve.analog_beam_list = - (nfapi_uint8_tlv_t *)malloc(nfapi_resp->analog_beamforming_ve.total_num_beams_vendor_ext.value * sizeof(nfapi_uint8_tlv_t)); - for (int i = 0; i < nfapi_resp->analog_beamforming_ve.total_num_beams_vendor_ext.value; ++i) { - FILL_TLV(nfapi_resp->analog_beamforming_ve.analog_beam_list[i], NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG, rand8()); - nfapi_resp->num_tlv++; - } - }*/ + */ } static void test_pack_unpack(nfapi_nr_config_request_scf_t *req) diff --git a/openair1/PHY/CMakeLists.txt b/openair1/PHY/CMakeLists.txt index 83e7dc0530..34629fc1c7 100644 --- a/openair1/PHY/CMakeLists.txt +++ b/openair1/PHY/CMakeLists.txt @@ -3,3 +3,6 @@ add_subdirectory(TOOLS) add_subdirectory(NR_TRANSPORT) add_subdirectory(CODING) add_subdirectory(MODULATION) +if (ENABLE_TESTS) + add_subdirectory(INIT/tests) +endif() \ No newline at end of file diff --git a/openair1/PHY/CODING/DOC/LDPCImplementation.md b/openair1/PHY/CODING/DOC/LDPCImplementation.md index 0e4a630f4b..56e7570de4 100644 --- a/openair1/PHY/CODING/DOC/LDPCImplementation.md +++ b/openair1/PHY/CODING/DOC/LDPCImplementation.md @@ -40,7 +40,6 @@ Linking C shared module libldpc_aal.so At runtime, to successfully use LDPC accelerators (e.g., Xilinx T2/Intel ACCs), you will need to install the corresponding drivers and tools. Please refer to the dedicated documentation at [LDPC_OFFLOAD_SETUP.md](file://../../../../doc/LDPC_OFFLOAD_SETUP.md). -<<<<<<< HEAD ``` ./nr-softmodem -O libconfig:gnb.band78.sa.fr1.106PRB.usrpb210.conf:dbgl5 --rfsim --rfsimulator.serveraddr server --log_config.gtpu_log_level info --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev 01:00.0 --nrLDPC_coding_aal.dpdk_core_list 0-1 ``` diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 97b39beaf8..4dddaf7e7e 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -438,7 +438,7 @@ int main(int argc, char *argv[]) int n_trials = 1; double SNR_step = 0.1; - randominit(0); + randominit(); int test_uncoded = 0; n_iter_stats_t dec_iter[400] = {0}; diff --git a/openair1/PHY/CODING/TESTBENCH/ltetest.c b/openair1/PHY/CODING/TESTBENCH/ltetest.c index 45abec1697..97d66de486 100644 --- a/openair1/PHY/CODING/TESTBENCH/ltetest.c +++ b/openair1/PHY/CODING/TESTBENCH/ltetest.c @@ -72,7 +72,7 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi PHY_vars_UE = malloc(sizeof(PHY_VARS_UE)); mac_xface = malloc(sizeof(MAC_xface)); - randominit(0); + randominit(); set_taus_seed(0); lte_frame_parms = &(PHY_vars_eNB->lte_frame_parms); @@ -367,7 +367,7 @@ int main(int argc, char *argv[]) int num_pdcch_symbols = 1; int subframe = 6; - randominit(0); + randominit(); logInit(); lte_param_init(1,1,1,0,0,3); diff --git a/openair1/PHY/CODING/TESTBENCH/pdcch_test.c b/openair1/PHY/CODING/TESTBENCH/pdcch_test.c index 873e9e19bc..2a752bfee8 100644 --- a/openair1/PHY/CODING/TESTBENCH/pdcch_test.c +++ b/openair1/PHY/CODING/TESTBENCH/pdcch_test.c @@ -47,7 +47,7 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx) PHY_config = malloc(sizeof(PHY_CONFIG)); mac_xface = malloc(sizeof(MAC_xface)); - randominit(0); + randominit(); set_taus_seed(0); lte_frame_parms = &(PHY_config->lte_frame_parms); @@ -241,8 +241,7 @@ int main(int argc, char *argv[]) PHY_vars = malloc(sizeof(PHY_VARS)); mac_xface = malloc(sizeof(MAC_xface)); - - randominit(0); + randominit(); set_taus_seed(0); ccodelte_init(); diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index e84a62775b..cb51f85aca 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -125,7 +125,7 @@ int main(int argc, char *argv[]) cpu_meas_enabled = 1; reset_meas(&timeEncoder); reset_meas(&timeDecoder); - randominit(0); + randominit(); crcTableInit(); if (polarMessageType == 0) { // PBCH diff --git a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c index a701a49d1a..275262428c 100644 --- a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c +++ b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c @@ -13,7 +13,7 @@ int main(int argc, char *argv[]) cpu_meas_enabled = 1; reset_meas(&timeEncoder); reset_meas(&timeDecoder); - randominit(0); + randominit(); int ret = 1; int arguments, iterations = 1000, messageLength = 11; diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index 81177a63cb..d2d963ade4 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -77,7 +77,7 @@ void lte_param_init(PHY_VARS_eNB **eNBp, eNB->RU_list[0] = ru; ru->num_eNB=1; srand(0); - randominit(0); + randominit(); set_taus_seed(0); frame_parms = &(eNB->frame_parms); frame_parms->N_RB_DL = N_RB_DL; //50 for 10MHz and 25 for 5 MHz diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index ad6400fc64..e3fc7db2af 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -299,8 +299,8 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, { NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; nfapi_nr_config_request_scf_t *gNB_config = &gNB->gNB_config; - //overwrite for new NR parameters + // overwrite with new NR parameters uint64_t rev_burst=0; for (int i=0; i<64; i++) rev_burst |= (((position_in_burst>>(63-i))&0x01)<carrier_config.num_tx_ant.value = fp->nb_antennas_tx; gNB_config->carrier_config.num_rx_ant.value = fp->nb_antennas_rx; - gNB_config->tdd_table.tdd_period.value = 0; - //gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED; - - if (mu==0) { - fp->dl_CarrierFreq = 2600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); - fp->ul_CarrierFreq = 2600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); - fp->nr_band = 38; - // fp->threequarter_fs= 0; - } else if (mu==1) { - fp->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); - fp->ul_CarrierFreq = 3600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); - fp->nr_band = 78; - // fp->threequarter_fs= 0; - } else if (mu==3) { - fp->dl_CarrierFreq = 27524520000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); - fp->ul_CarrierFreq = 27524520000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); - fp->nr_band = 261; - // fp->threequarter_fs= 0; + switch (mu) { + case 0: + gNB->gNB_config.tdd_table.tdd_period.value = 7; + fp->dl_CarrierFreq = 2600000000; + fp->ul_CarrierFreq = 2600000000; + fp->nr_band = 38; + break; + case 1: + gNB->gNB_config.tdd_table.tdd_period.value = 6; + fp->dl_CarrierFreq = 3600000000; + fp->ul_CarrierFreq = 3600000000; + fp->nr_band = 78; + break; + case 3: + gNB->gNB_config.tdd_table.tdd_period.value = 3; + fp->dl_CarrierFreq = 27524520000; + fp->ul_CarrierFreq = 27524520000; + fp->nr_band = 261; + break; + default: + printf("unsupported numerology %d\n", mu); + exit(-1); } - fp->threequarter_fs = 0; frequency_range_t frequency_range = get_freq_range_from_band(fp->nr_band); int bw_index = get_supported_band_index(mu, frequency_range, N_RB_DL); gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index); diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 7ab8a8863d..e5c8e975c9 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -20,7 +20,6 @@ */ #include "nr_phy_init.h" -#include "PHY/phy_extern_nr_ue.h" #include "openair1/PHY/defs_RU.h" #include "openair1/PHY/impl_defs_nr.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -338,8 +337,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) free_and_zero(ue->prs_vars[idx]); } - free_and_zero(ue->ntn_config_message); - sl_ue_free(ue); } diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index cc31dc173a..6fbfcb3cac 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -199,14 +199,26 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL) AssertFatal(1==0,"Invalid numerology index %d", mu); } - if(fp->threequarter_fs) - fp->ofdm_symbol_size = 3 * 128; - else - fp->ofdm_symbol_size = 4 * 128; + // Start with FFT size 512 + fp->ofdm_symbol_size = 512; - while(fp->ofdm_symbol_size < N_RB_DL * 12) + // Choose the right FFT size for the BW + while(fp->ofdm_symbol_size < N_RB_DL * NR_NB_SC_PER_RB) fp->ofdm_symbol_size <<= 1; + // Do 3/4 sampling + if (fp->threequarter_fs) { + const uint16_t threeq_fft_size = fp->ofdm_symbol_size * 3 / 4; + if (threeq_fft_size < (N_RB_DL * NR_NB_SC_PER_RB)) { + // 3/4 sampling FFT size not enough + warn_higher_threequarter_fs(N_RB_DL, fp->numerology_index); + // Choose 2 times 3/4 sampling + fp->ofdm_symbol_size = threeq_fft_size << 1; + } else { + fp->ofdm_symbol_size = threeq_fft_size; + } + } + fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2); fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9; fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu)); @@ -259,33 +271,116 @@ uint32_t get_samples_per_slot(int slot, const NR_DL_FRAME_PARMS *fp) return samp_count; } -uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp) +uint32_t get_samples_symbol_duration(const NR_DL_FRAME_PARMS *fp, int slot, int start_symbol, int num_symbols) { - uint32_t slot_idx = 0; - int samples_till_the_slot = fp->get_samples_per_slot(slot_idx,fp)-1; - timestamp_rx = timestamp_rx%fp->samples_per_frame; + int end_symbol = start_symbol + num_symbols - 1; + AssertFatal(start_symbol <= end_symbol && start_symbol >= 0 && end_symbol < fp->symbols_per_slot, + "Symbol range is invalid start_symbol %d, num_symbols %d symbols_per_slot %d\n", + start_symbol, + num_symbols, + fp->symbols_per_slot); + if (num_symbols == fp->symbols_per_slot) { + return get_samples_per_slot(slot, fp); + } + uint32_t num_samples = 0; + int num_symbols_added = 0; - while (timestamp_rx > samples_till_the_slot) { - slot_idx++; - samples_till_the_slot += fp->get_samples_per_slot(slot_idx,fp); - } - return slot_idx; + // Handle symbols with different nb_prefix_samples0 + if (fp->numerology_index == 0) { + // Add symbol 0 + if (start_symbol == 0) { + num_samples += fp->nb_prefix_samples0 + fp->ofdm_symbol_size; + num_symbols_added++; + } + // Add symbol 7 + if (start_symbol <= 7 && end_symbol >= 7) { + num_samples += fp->nb_prefix_samples0 + fp->ofdm_symbol_size; + num_symbols_added++; + } + } else { + // Add first symbol + if (start_symbol == 0) { + num_samples += (slot % (fp->slots_per_subframe / 2)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0; + num_samples += fp->ofdm_symbol_size; + num_symbols_added++; + } + } + + int num_symbols_left = max(0, num_symbols - num_symbols_added); + num_samples += num_symbols_left * (fp->nb_prefix_samples + fp->ofdm_symbol_size); + return num_samples; } -uint32_t get_samples_slot_timestamp(int slot, const NR_DL_FRAME_PARMS *fp, unsigned int sl_ahead) +uint32_t get_samples_symbol_timestamp(const NR_DL_FRAME_PARMS *fp, int slot, int symbol) { - uint32_t samp_count = 0; - - if(!sl_ahead) { - for(unsigned int idx_slot = 0; idx_slot < slot; idx_slot++) - samp_count += fp->get_samples_per_slot(idx_slot, fp); - } else { - for (unsigned int idx_slot = slot; idx_slot < slot + sl_ahead; idx_slot++) - samp_count += fp->get_samples_per_slot(idx_slot, fp); + if (symbol == 0) { + return 0; } + + return get_samples_symbol_duration(fp, slot, 0, symbol); +} + +uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp) +{ + timestamp_rx = timestamp_rx % fp->samples_per_frame; + if (timestamp_rx < fp->samples_per_slot0) + return 0; + + if (fp->numerology_index == 0) + return timestamp_rx / fp->samples_per_subframe; + + const unsigned int num_half_sf = timestamp_rx / (fp->samples_per_subframe / 2); + const unsigned int slot_per_half_sf = fp->slots_per_subframe / 2; + + uint32_t slot_count = num_half_sf * slot_per_half_sf; + int samp_idx = num_half_sf * (fp->samples_per_subframe / 2) - 1; + + // Remaining samples + if (samp_idx < timestamp_rx) { + slot_count++; + samp_idx += fp->samples_per_slot0; // First slot of half subframe + } + if (samp_idx < timestamp_rx) { + const unsigned int rem_samples = timestamp_rx - samp_idx; + const unsigned int num_slots = ceil((double)rem_samples / fp->samples_per_slotN0); + slot_count += num_slots; + } + + return slot_count - 1; +} + +uint32_t get_samples_slot_timestamp(const NR_DL_FRAME_PARMS *fp, unsigned int slot) +{ + if (slot == 0) + return 0; + + if (fp->numerology_index == 0) + return slot * fp->samples_per_subframe; + + uint32_t samp_count = 0; + // Number of half subframes + const unsigned int num_half_sf = slot / (fp->slots_per_subframe / 2); + samp_count += num_half_sf * fp->samples_per_subframe / 2; + + // Remaining slots + unsigned int rem_slots = slot % (fp->slots_per_subframe / 2); + if (rem_slots > 0) { + samp_count += fp->samples_per_slot0; // First slot of the last half subframe + rem_slots--; + } + samp_count += rem_slots * fp->samples_per_slotN0; // Remaining slots of the last half subframe + return samp_count; } +uint32_t get_samples_slot_duration(const NR_DL_FRAME_PARMS *fp, unsigned int start_slot, unsigned int num_slots) +{ + if (start_slot == 0 && num_slots == 0) + return 0; + + return (get_samples_slot_timestamp(fp, start_slot + num_slots) - get_samples_slot_timestamp(fp, start_slot)); +} + void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS *fp) { @@ -319,12 +414,11 @@ void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS * fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; fp->samples_per_slotN0 = (fp->nb_prefix_samples + fp->ofdm_symbol_size) * fp->symbols_per_slot; - fp->samples_per_slot0 = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); - fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 + - (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_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 + + (fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2); + fp->samples_per_slot0 = fp->numerology_index == 0 ? fp->samples_per_subframe + : fp->nb_prefix_samples0 + ((fp->symbols_per_slot - 1) * fp->nb_prefix_samples) + + (fp->symbols_per_slot * fp->ofdm_symbol_size); fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = get_freq_range_from_freq(fp->dl_CarrierFreq); @@ -402,11 +496,11 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; fp->samples_per_slotN0 = (fp->nb_prefix_samples + fp->ofdm_symbol_size) * fp->symbols_per_slot; - fp->samples_per_slot0 = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); - fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 + - (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->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 + + (fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2); + fp->samples_per_slot0 = fp->numerology_index == 0 ? fp->samples_per_subframe + : fp->nb_prefix_samples0 + ((fp->symbols_per_slot - 1) * fp->nb_prefix_samples) + + (fp->symbols_per_slot * fp->ofdm_symbol_size); fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = get_freq_range_from_freq(fp->dl_CarrierFreq); @@ -460,11 +554,14 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP; frame_parms->samples_per_slot_wCP = frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size; frame_parms->samples_per_slotN0 = (frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) * frame_parms->symbols_per_slot; - frame_parms->samples_per_slot0 = frame_parms->nb_prefix_samples0 + ((frame_parms->symbols_per_slot-1)*frame_parms->nb_prefix_samples) + (frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size); - frame_parms->samples_per_subframe = (frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size) * 2 + - (frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) * (frame_parms->symbols_per_slot * frame_parms->slots_per_subframe - 2); - frame_parms->get_samples_per_slot = &get_samples_per_slot; - frame_parms->get_samples_slot_timestamp = &get_samples_slot_timestamp; + frame_parms->samples_per_subframe = (frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size) * 2 + + (frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) + * (frame_parms->symbols_per_slot * frame_parms->slots_per_subframe - 2); + frame_parms->samples_per_slot0 = frame_parms->numerology_index == 0 + ? frame_parms->samples_per_subframe + : frame_parms->nb_prefix_samples0 + + ((frame_parms->symbols_per_slot - 1) * frame_parms->nb_prefix_samples) + + (frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size); frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe; LOG_W(PHY, "samples_per_subframe %d/per second %d, wCP %d\n", frame_parms->samples_per_subframe, 1000*frame_parms->samples_per_subframe, frame_parms->samples_per_subframe_wCP); @@ -560,12 +657,11 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp, fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; fp->samples_per_slot_wCP = fp->symbols_per_slot * fp->ofdm_symbol_size; fp->samples_per_slotN0 = (fp->nb_prefix_samples + fp->ofdm_symbol_size) * fp->symbols_per_slot; - fp->samples_per_slot0 = - fp->nb_prefix_samples0 + ((fp->symbols_per_slot - 1) * fp->nb_prefix_samples) + (fp->symbols_per_slot * fp->ofdm_symbol_size); fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2 + (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->samples_per_slot0 = fp->numerology_index == 0 ? fp->samples_per_subframe + : fp->nb_prefix_samples0 + ((fp->symbols_per_slot - 1) * fp->nb_prefix_samples) + + (fp->symbols_per_slot * fp->ofdm_symbol_size); fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = get_freq_range_from_freq(fp->sl_CarrierFreq); diff --git a/openair1/PHY/INIT/nr_phy_init.h b/openair1/PHY/INIT/nr_phy_init.h index f556498f0f..bfe935d93f 100644 --- a/openair1/PHY/INIT/nr_phy_init.h +++ b/openair1/PHY/INIT/nr_phy_init.h @@ -55,10 +55,11 @@ void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES], void phy_init_nr_top(PHY_VARS_NR_UE *ue); void phy_term_nr_top(void); +#ifndef __cplusplus void init_delay_table(uint16_t ofdm_symbol_size, int max_delay_comp, int max_ofdm_symbol_size, c16_t delay_table[][max_ofdm_symbol_size]); - +#endif void sl_ue_phy_init(PHY_VARS_NR_UE *UE); #endif diff --git a/openair1/PHY/INIT/tests/CMakeLists.txt b/openair1/PHY/INIT/tests/CMakeLists.txt new file mode 100644 index 0000000000..6c532ebd99 --- /dev/null +++ b/openair1/PHY/INIT/tests/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(test_nr_frame_params test_nr_frame_params.cpp) +target_link_libraries(test_nr_frame_params PRIVATE LOG minimal_lib PHY_NR -lm GTest::gtest) +add_dependencies(tests test_nr_frame_params) +add_test(NAME test_nr_frame_params COMMAND ./test_nr_frame_params) diff --git a/openair1/PHY/INIT/tests/test_nr_frame_params.cpp b/openair1/PHY/INIT/tests/test_nr_frame_params.cpp new file mode 100644 index 0000000000..e3e541f8ab --- /dev/null +++ b/openair1/PHY/INIT/tests/test_nr_frame_params.cpp @@ -0,0 +1,177 @@ +/* + * 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 "gtest/gtest.h" +extern "C" { +#include +#include "openair1/PHY/defs_nr_common.h" +#include "openair1/PHY/INIT/nr_phy_init.h" + +static softmodem_params_t softmodem_params; +softmodem_params_t *get_softmodem_params(void) +{ + return &softmodem_params; +} +} + +uint32_t ref_get_samples_slot_timestamp(NR_DL_FRAME_PARMS *fp, unsigned int slot) +{ + uint32_t samp_count = 0; + for (unsigned int i = 0; i < slot; i++) { + samp_count += get_samples_per_slot(i, fp); + } + return samp_count; +} + +uint32_t ref_get_slot_from_timestamp(openair0_timestamp ts, NR_DL_FRAME_PARMS *fp) +{ + uint32_t slot_idx = 0; + int samples_till_the_slot = get_samples_per_slot(slot_idx, fp) - 1; + ts = ts % fp->samples_per_frame; + + while (ts > samples_till_the_slot) { + slot_idx++; + samples_till_the_slot += get_samples_per_slot(slot_idx, fp); + } + return slot_idx; +} + +void test_coherence_symbol_api(NR_DL_FRAME_PARMS *fp) +{ + EXPECT_EQ(get_samples_symbol_timestamp(fp, 0, 0), get_samples_slot_timestamp(fp, 0)); + + for (int slot = 0; slot < 4; slot++) { + EXPECT_EQ(get_samples_symbol_duration(fp, slot, 0, fp->symbols_per_slot) + get_samples_slot_timestamp(fp, slot), + get_samples_slot_timestamp(fp, slot + 1)); + } + + for (int symbol = 0; symbol < fp->symbols_per_slot - 1; symbol++) { + EXPECT_EQ(get_samples_symbol_timestamp(fp, 0, symbol + 1) - get_samples_symbol_timestamp(fp, 0, symbol), + get_samples_symbol_duration(fp, 0, symbol, 1)); + } +} + +void test_coherence_slot_api(NR_DL_FRAME_PARMS *fp) +{ + for (unsigned int slot = 0; slot < fp->slots_per_frame; slot++) { + EXPECT_EQ(get_samples_slot_timestamp(fp, slot), ref_get_samples_slot_timestamp(fp, slot)); + } + + openair0_timestamp ts = get_samples_per_slot(0, fp); + // When timestamp is the last sample of the slot + EXPECT_EQ(get_slot_from_timestamp(ts - 1, fp), 0); + for (unsigned int slot = 0; slot < fp->slots_per_frame; slot++) { + // When timestamp is the first sample of the slot + ts = ref_get_samples_slot_timestamp(fp, slot); + EXPECT_EQ(get_slot_from_timestamp(ts, fp), slot); + // When timestamp is anywhere in the slot + ts += (rand() % fp->samples_per_slotN0); + EXPECT_EQ(get_slot_from_timestamp(ts, fp), slot); + } +} + +TEST(nr_frame_params, test_mu_3) +{ + NR_DL_FRAME_PARMS fp; + int mu = NR_MU_3; + memset(&fp, 0, sizeof(fp)); + nfapi_nr_config_request_scf_t cfg; + cfg.carrier_config.num_rx_ant.value = 4; + cfg.carrier_config.num_tx_ant.value = 4; + cfg.carrier_config.dl_grid_size[mu].value = 66; + cfg.carrier_config.ul_grid_size[mu].value = 66; + cfg.cell_config.frame_duplex_type.value = TDD; + cfg.ssb_config.scs_common.value = mu; + fp.dl_CarrierFreq = 27524520000; + fp.nr_band = 261; + nr_init_frame_parms(&cfg, &fp); + nr_dump_frame_parms(&fp); + test_coherence_symbol_api(&fp); + test_coherence_slot_api(&fp); +} + +TEST(nr_frame_params, test_mu_2) +{ + NR_DL_FRAME_PARMS fp; + int mu = NR_MU_2; + memset(&fp, 0, sizeof(fp)); + nfapi_nr_config_request_scf_t cfg; + cfg.carrier_config.num_rx_ant.value = 4; + cfg.carrier_config.num_tx_ant.value = 4; + cfg.carrier_config.dl_grid_size[mu].value = 51; + cfg.carrier_config.ul_grid_size[mu].value = 51; + cfg.cell_config.frame_duplex_type.value = TDD; + cfg.ssb_config.scs_common.value = mu; + fp.dl_CarrierFreq = 27524520000; + fp.nr_band = 261; + nr_init_frame_parms(&cfg, &fp); + nr_dump_frame_parms(&fp); + test_coherence_symbol_api(&fp); + test_coherence_slot_api(&fp); +} + +TEST(nr_frame_params, test_mu_1) +{ + NR_DL_FRAME_PARMS fp; + int mu = NR_MU_1; + memset(&fp, 0, sizeof(fp)); + nfapi_nr_config_request_scf_t cfg; + cfg.carrier_config.num_rx_ant.value = 4; + cfg.carrier_config.num_tx_ant.value = 4; + cfg.carrier_config.dl_grid_size[mu].value = 106; + cfg.carrier_config.ul_grid_size[mu].value = 106; + cfg.cell_config.frame_duplex_type.value = TDD; + cfg.ssb_config.scs_common.value = mu; + fp.dl_CarrierFreq = 3600000000; + fp.nr_band = 78; + nr_init_frame_parms(&cfg, &fp); + nr_dump_frame_parms(&fp); + test_coherence_symbol_api(&fp); + test_coherence_slot_api(&fp); +} + +TEST(nr_frame_params, test_mu_0) +{ + int mu = NR_MU_0; + NR_DL_FRAME_PARMS fp; + memset(&fp, 0, sizeof(fp)); + nfapi_nr_config_request_scf_t cfg; + cfg.carrier_config.num_rx_ant.value = 4; + cfg.carrier_config.num_tx_ant.value = 4; + cfg.carrier_config.dl_grid_size[mu].value = 216; + cfg.carrier_config.ul_grid_size[mu].value = 216; + cfg.cell_config.frame_duplex_type.value = TDD; + cfg.ssb_config.scs_common.value = mu; + fp.dl_CarrierFreq = 2600000000; + fp.nr_band = 38; + nr_init_frame_parms(&cfg, &fp); + nr_dump_frame_parms(&fp); + test_coherence_symbol_api(&fp); + test_coherence_slot_api(&fp); +} + +int main(int argc, char **argv) +{ + uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY); + logInit(); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c b/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c index 998b95d0d3..86a4b93ddd 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c @@ -12,11 +12,7 @@ data storage. */ #include #include #include -#if defined RHEL_RELEASE_CODE -#include -#else #include -#endif #include #include #include diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 8bdd7e760b..bb03f8ef7b 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -78,7 +78,7 @@ void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n \param sample_offset offset within rxdata (points to beginning of subframe) */ -int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, +int nr_slot_fep_ul(const NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdata, int32_t *rxdataF, unsigned char symbol, @@ -139,6 +139,15 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, int first_symbol, int nsymb); +void nr_ofdm_demod_and_rx_rotation(c16_t **rxdata, + c16_t **rxdataF, + const NR_DL_FRAME_PARMS *fp, + int nb_antennas, + int slot, + int slot_offsetF, + enum nr_Link linktype, + bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]); + void perform_symbol_rotation(NR_DL_FRAME_PARMS *fp, double f0, c16_t *symbol_rotation); void init_symbol_rotation(NR_DL_FRAME_PARMS *fp); diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 6cc8cbe7c5..c3311fb78a 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -326,4 +326,3 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, } } } - diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 50e19d8563..c012d39d82 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -80,7 +80,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, // For Sidelink 16 frames worth of samples is processed to find SSB, for 5G-NR 2. const unsigned int total_samples = (is_sl) ? 16 * frame_parms->samples_per_frame : 2 * frame_parms->samples_per_frame; - unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); + unsigned int rx_offset = get_samples_slot_timestamp(frame_parms, slot); const unsigned int abs_symbol = slot * frame_parms->symbols_per_slot + symbol; for (int idx_symb = slot * frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) rx_offset += (idx_symb % (0x7 << frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; @@ -119,7 +119,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, if (ue && ue->cont_fo_comp) { start_meas_nr_ue_phy(ue, RX_FO_COMPENSATION_STATS); - nr_fo_compensation(ue->freq_offset, + nr_fo_compensation(ue->dl_Doppler_shift + ue->freq_offset, frame_parms->samples_per_subframe, rx_offset, rxdata_symb_ptr[aa], @@ -135,7 +135,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, return 0; } -int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, +int nr_slot_fep_ul(const NR_DL_FRAME_PARMS *frame_parms, int32_t *rxdata, int32_t *rxdataF, unsigned char symbol, @@ -150,7 +150,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, int32_t tmp_dft_in[8192] __attribute__ ((aligned (32))); // offset of first OFDM symbol - unsigned int rxdata_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); + unsigned int rxdata_offset = get_samples_slot_timestamp(frame_parms, Ns); unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol; for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) rxdata_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; @@ -237,3 +237,27 @@ void apply_nr_rotation_symbol_RX(const NR_DL_FRAME_PARMS *frame_parms, 15); } } + +void nr_ofdm_demod_and_rx_rotation(c16_t **rxdata, + c16_t **rxdataF, + const NR_DL_FRAME_PARMS *fp, + int nb_antennas, + int slot, + int slot_offsetF, + enum nr_Link linktype, + bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]) +{ + for (int aa = 0; aa < nb_antennas; aa++) { + for (uint8_t symbol = 0; symbol < fp->symbols_per_slot; symbol++) { + if (was_symbol_used[symbol] == true) { + nr_slot_fep_ul(fp, (int32_t *)&rxdata[aa][0], (int32_t *)&rxdataF[aa][slot_offsetF], symbol, slot, 0); + apply_nr_rotation_symbol_RX(fp, + &rxdataF[aa][slot_offsetF + symbol * fp->ofdm_symbol_size], + fp->symbol_rotation[linktype], + fp->N_RB_UL, + slot, + symbol); + } + } + } +} diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index a1fde35b00..89aba954e9 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -36,49 +36,73 @@ #define I0_SKIP_DC 1 -int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, - const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]) +void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size, + const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], + uint8_t ant, + uint8_t N_ap, + uint32_t samples_per_frame, + uint16_t *ta_offset, + int16_t *ta_offset_nsec) { - int timing_advance = 0; - int max_val = 0; - - for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { - int temp = 0; - for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { - int Re = ((c16_t*)srs_estimated_channel_time[aa])[i].r; - int Im = ((c16_t*)srs_estimated_channel_time[aa])[i].i; - temp += (Re*Re/2) + (Im*Im/2); + int64_t mean_val = 0; + int64_t max_val = 0; + int32_t max_idx = 0; + int16_t srs_toa = 0; + int16_t ofdm_os_size = NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size; + for (int k = 0; k < ofdm_os_size; k++) { + int64_t abs_val = 0; + for (int p_index = 0; p_index < N_ap; p_index++) { + abs_val += squaredMod(srs_estimated_channel_time[p_index][k]); } - if (temp > max_val) { - timing_advance = i; - max_val = temp; + mean_val += abs_val; + if (abs_val > max_val) { + max_val = abs_val; + max_idx = k; } } + max_val = max_val / N_ap; + mean_val = mean_val / (N_ap * ofdm_os_size); - if (timing_advance > frame_parms->ofdm_symbol_size/2) { - timing_advance = timing_advance - frame_parms->ofdm_symbol_size; - } + if (max_idx > ofdm_os_size >> 1) + max_idx = max_idx - ofdm_os_size; - // Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size - const uint16_t bw_scaling = frame_parms->ofdm_symbol_size >> 7; + // Check for detection threshold + if ((mean_val != 0) && (max_val / mean_val > NR_SRS_DETECTION_THRESHOLD)) { + srs_toa = max_idx / NR_SRS_IDFT_OVERSAMP_FACTOR; - // do some integer rounding to improve TA accuracy - int sync_pos_rounded; - if (timing_advance > 0) { - sync_pos_rounded = timing_advance + (bw_scaling >> 1) - 1; + // restrict the computation of ta_offset to antenna 0 + if (ant == 0) { + // Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size + const uint16_t bw_scaling = ofdm_symbol_size >> 7; + + // do some integer rounding to improve TA accuracy + int sync_pos_rounded; + if (srs_toa > 0) { + sync_pos_rounded = srs_toa + (bw_scaling >> 1) - 1; + } else { + sync_pos_rounded = srs_toa - (bw_scaling >> 1) + 1; + } + + *ta_offset = sync_pos_rounded / bw_scaling; + + // put timing advance command in 0..63 range + *ta_offset = BOUNDED_EVAL(0, *ta_offset + 31, 63); + } + *ta_offset_nsec = (max_idx * 1e9) / (NR_SRS_IDFT_OVERSAMP_FACTOR * samples_per_frame * 100); } else { - sync_pos_rounded = timing_advance - (bw_scaling >> 1) + 1; + *ta_offset = 0xFFFF; + *ta_offset_nsec = 0x8000; } - int timing_advance_update = sync_pos_rounded / bw_scaling; - - // put timing advance command in 0..63 range - timing_advance_update += 31; - - if (timing_advance_update < 0) timing_advance_update = 0; - if (timing_advance_update > 63) timing_advance_update = 63; - - return timing_advance_update; + LOG_D(NR_PHY, + "SRS estimatd ToA %d [RX ant %d]: TA offset %d, TA offset ns %d (max_val %ld, mean_val %ld, max_idx %d)\n", + srs_toa, + ant, + *ta_offset, + *ta_offset_nsec, + max_val, + mean_val, + max_idx); } void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) { diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index d73a315354..f9203f488f 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -769,28 +769,29 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, } // Antenna loop } -int nr_srs_channel_estimation( - const PHY_VARS_gNB *gNB, - const int frame, - const int slot, - const nfapi_nr_srs_pdu_t *srs_pdu, - const nr_srs_info_t *nr_srs_info, - const c16_t **srs_generated_signal, - c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], - c16_t srs_received_noise[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], - c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports] - [gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], - c16_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - c16_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - int16_t *snr_per_rb, - int8_t *snr) +int nr_srs_channel_estimation(int ant, + int p_index, + uint16_t ofdm_symbol_size, + uint16_t first_carrier_offset, + uint8_t N_symb_SRS, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const c16_t *srs_generated_signal, + c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS], + c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS], + c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS], + c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], + c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], + uint32_t *signal_power, + uint32_t *noise_power, + int16_t *noise_power_per_rb) { #ifdef SRS_DEBUG LOG_I(NR_PHY, "Calling %s function\n", __FUNCTION__); #endif - const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB; + const uint64_t subcarrier_offset = first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB; + const uint64_t first_subcarrier = (first_carrier_offset - (ofdm_symbol_size >> 1)) + srs_pdu->bwp_start * NR_NB_SC_PER_RB; const uint8_t N_ap = 1 << srs_pdu->num_ant_ports; const uint8_t K_TC = 2 << srs_pdu->comb_size; @@ -800,249 +801,268 @@ int nr_srs_channel_estimation( if (N_ap == 4 && ((K_TC == 2 && srs_pdu->cyclic_shift >= 4) || (K_TC == 4 && srs_pdu->cyclic_shift >= 6))) { fd_cdm = 2; } + uint16_t subcarrier; - c16_t srs_ls_estimated_channel[frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)]; - uint8_t mem_offset = ((16 - ((intptr_t)&srs_estimated_channel_freq[0][0][subcarrier_offset + nr_srs_info->k_0_p[0][0]])) & 0xF) - >> 2; // >> 2 <=> /sizeof(int32_t) + c16_t srs_ls_estimated_channel[ofdm_symbol_size * N_symb_SRS]; + c16_t srs_estimated_channel_freq_avg[ofdm_symbol_size]; + memset(srs_ls_estimated_channel, 0, ofdm_symbol_size * N_symb_SRS * sizeof(c16_t)); + memset(srs_estimated_channel_freq_avg, 0, ofdm_symbol_size * sizeof(c16_t)); - // filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0} - // The End of OFDM symbol corresponds to the position of last 16384 in the filter - // The c16multaddVectRealComplex applies the remaining 8 zeros of filter, therefore, to avoid a buffer overflow, - // we added 8 in the array size - c16_t srs_est[frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) + mem_offset + 8] __attribute__((aligned(32))); - c16_t ls_estimated = {0}; + for (int srs_symb = 0; srs_symb < N_symb_SRS; srs_symb++) { + uint16_t srs_symbol_offset = srs_symb * ofdm_symbol_size; - for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { - for (int p_index = 0; p_index < N_ap; p_index++) { - memset(srs_ls_estimated_channel, 0, frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) * sizeof(c16_t)); - memset(srs_est, 0, (frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) + mem_offset) * sizeof(c16_t)); + // Additional 4 in the array size is needed to maintain 16 byte memory alignment required for AVX2 instructions in channel + // interpolation + c16_t srs_est[ofdm_symbol_size + 4] __attribute__((aligned(32))); + memset(srs_est, 0, (ofdm_symbol_size + 4) * sizeof(c16_t)); + + // Estimate 16 byte memory alignment offset for the first SRS subcarrier to use AVX2 instructions in channel interpolation + uint8_t mem_offset = (16 - (((intptr_t)&srs_est[first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb]]) & 0xF)) + >> 2; // >> 2 <=> /sizeof(int32_t) + + c16_t ls_estimated = {0}; #ifdef SRS_DEBUG - LOG_I(NR_PHY, "====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant); + LOG_I(NR_PHY, "====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant); + LOG_I(NR_PHY, "============================== SRS symbol index %d ===========================\n", srs_symb); #endif - uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; - if (subcarrier >= frame_parms->ofdm_symbol_size) { - subcarrier -= frame_parms->ofdm_symbol_size; - } - - c16_t *srs_estimated_channel16 = &srs_est[subcarrier + mem_offset]; - - for (int k = 0; k < M_sc_b_SRS; k++) { - if (k % fd_cdm == 0) { - ls_estimated = (c16_t){0, 0}; - uint16_t subcarrier_cdm = subcarrier; - - for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) { - c16_t generated_srs = srs_generated_signal[p_index][subcarrier_cdm]; - c16_t received_srs = srs_received_signal[ant][subcarrier_cdm]; - // We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the real and imaginary parts of - // generated_srs. So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 - // bits. - ls_estimated = c16maddConjShift(generated_srs, received_srs, ls_estimated, nr_srs_info->srs_generated_signal_bits); - - // Subcarrier increment - subcarrier_cdm += K_TC; - if (subcarrier_cdm >= frame_parms->ofdm_symbol_size) { - subcarrier_cdm = subcarrier_cdm - frame_parms->ofdm_symbol_size; - } - } - } - - srs_ls_estimated_channel[subcarrier] = ls_estimated; - -#ifdef SRS_DEBUG - int subcarrier_log = subcarrier - subcarrier_offset; - if (subcarrier_log < 0) { - subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; - } - if (subcarrier_log % 12 == 0) { - LOG_I(NR_PHY, "------------------------------------ %d ------------------------------------\n", subcarrier_log / 12); - LOG_I(NR_PHY, "\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n"); - } - LOG_I(NR_PHY, - "(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", - subcarrier_log, - srs_generated_signal[p_index][subcarrier].r, - srs_generated_signal[p_index][subcarrier].i, - srs_received_signal[ant][subcarrier].r, - srs_received_signal[ant][subcarrier].i, - ls_estimated.r, - ls_estimated.i); -#endif - - const uint16_t sc_offset = subcarrier + mem_offset; - - // Channel interpolation - if (srs_pdu->comb_size == 0) { - if (k == 0) { // First subcarrier case - // filt8_start is {12288,8192,4096,0,0,0,0,0} - c16multaddVectRealComplex(filt8_start, &ls_estimated, srs_estimated_channel16, 8); - } else if (subcarrier < K_TC) { // Start of OFDM symbol case - // filt8_start is {12288,8192,4096,0,0,0,0,0} - srs_estimated_channel16 = &srs_est[subcarrier]; - const short *filter = mem_offset == 0 ? filt8_start : filt8_start_shift2; - c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8); - } else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size - || k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases - // filt8_end is {4096,8192,12288,16384,0,0,0,0} - const short *filter = mem_offset == 0 || k == (M_sc_b_SRS - 1) ? filt8_end : filt8_end_shift2; - c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8); - } else if (k % 2 == 1) { // 1st middle case - // filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0} - c16multaddVectRealComplex(filt8_middle2, &ls_estimated, srs_estimated_channel16, 8); - } else if (k % 2 == 0) { // 2nd middle case - // filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0} - c16multaddVectRealComplex(filt8_middle4, &ls_estimated, srs_estimated_channel16, 8); - srs_estimated_channel16 = &srs_est[sc_offset]; - } - } else { - if (k == 0) { // First subcarrier case - // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} - c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16); - } else if (subcarrier < K_TC) { // Start of OFDM symbol case - srs_estimated_channel16 = &srs_est[sc_offset]; - // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} - c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16); - } else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size - || k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases - // filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0} - c16multaddVectRealComplex(filt16_end, &ls_estimated, srs_estimated_channel16, 16); - } else { // Middle case - // filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0} - c16multaddVectRealComplex(filt16_middle4, &ls_estimated, srs_estimated_channel16, 16); - srs_estimated_channel16 = &srs_est[sc_offset]; - } - } - - // Subcarrier increment - subcarrier += K_TC; - if (subcarrier >= frame_parms->ofdm_symbol_size) { - subcarrier -= frame_parms->ofdm_symbol_size; - } - - } // for (int k = 0; k < M_sc_b_SRS; k++) - - memcpy(srs_estimated_channel_freq[ant][p_index], - &srs_est[mem_offset], - (frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)) * sizeof(c16_t)); - -#ifdef SRS_DEBUG - subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; - if (subcarrier >= frame_parms->ofdm_symbol_size) { - subcarrier -= frame_parms->ofdm_symbol_size; - } - - for (int k = 0; k < K_TC * M_sc_b_SRS; k++) { - int subcarrier_log = subcarrier - subcarrier_offset; - if (subcarrier_log < 0) { - subcarrier_log = subcarrier_log + frame_parms->ofdm_symbol_size; - } - - if (subcarrier_log % 12 == 0) { - LOG_I(NR_PHY, "------------------------------------- %d -------------------------------------\n", subcarrier_log / 12); - LOG_I(NR_PHY, "\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm__\n"); - } - - LOG_I(NR_PHY, - "(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", - subcarrier_log, - srs_ls_estimated_channel[subcarrier].r, - srs_ls_estimated_channel[subcarrier].i, - srs_estimated_channel_freq[ant][p_index][subcarrier].r, - srs_estimated_channel_freq[ant][p_index][subcarrier].i, - srs_received_noise[ant][subcarrier].r, - srs_received_noise[ant][subcarrier].i); - - // Subcarrier increment - subcarrier++; - if (subcarrier >= frame_parms->ofdm_symbol_size) { - subcarrier -= frame_parms->ofdm_symbol_size; - } - } -#endif - - // Convert to time domain - freq2time(gNB->frame_parms.ofdm_symbol_size, - (int16_t *)srs_estimated_channel_freq[ant][p_index], - (int16_t *)srs_estimated_channel_time[ant][p_index]); - - memcpy(srs_estimated_channel_time_shifted[ant][p_index], - &srs_estimated_channel_time[ant][p_index][gNB->frame_parms.ofdm_symbol_size >> 1], - (gNB->frame_parms.ofdm_symbol_size >> 1) * sizeof(c16_t)); - - memcpy(&srs_estimated_channel_time_shifted[ant][p_index][gNB->frame_parms.ofdm_symbol_size >> 1], - srs_estimated_channel_time[ant][p_index], - (gNB->frame_parms.ofdm_symbol_size >> 1) * sizeof(c16_t)); - - } // for (int p_index = 0; p_index < N_ap; p_index++) - } // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) - - // Compute wideband SNR - int tot_subcarriers = m_SRS_b * NR_NB_SC_PER_RB; - uint32_t signal_power = 0; - uint32_t noise_power = 0; - for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { - for (int p_index = 0; p_index < N_ap; p_index++) { - uint16_t subcarrier0 = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; - if (subcarrier0 >= frame_parms->ofdm_symbol_size) { - subcarrier0 -= frame_parms->ofdm_symbol_size; - } - if (subcarrier0 + tot_subcarriers < frame_parms->ofdm_symbol_size) { - signal_power += signal_energy_nodc(&srs_estimated_channel_freq[ant][p_index][subcarrier0], tot_subcarriers); - if (p_index == 0) - noise_power += signal_energy_nodc(&srs_received_noise[ant][subcarrier0], tot_subcarriers); - } else { - int size1 = frame_parms->ofdm_symbol_size - subcarrier0; - int size2 = tot_subcarriers - size1; - uint64_t signal_power_p1 = signal_energy_nodc(&srs_estimated_channel_freq[ant][p_index][subcarrier0], size1) * size1; - uint64_t signal_power_p2 = signal_energy_nodc(&srs_estimated_channel_freq[ant][p_index][0], size2) * size2; - signal_power += (signal_power_p1 + signal_power_p2) / tot_subcarriers; - if (p_index == 0) { - uint64_t noise_power_p1 = signal_energy_nodc(&srs_received_noise[ant][subcarrier0], size1) * size1; - uint64_t noise_power_p2 = signal_energy_nodc(&srs_received_noise[ant][0], size2) * size2; - noise_power += (noise_power_p1 + noise_power_p2) / tot_subcarriers; - } - } + subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb]; + if (subcarrier >= ofdm_symbol_size) { + subcarrier -= ofdm_symbol_size; } + + uint16_t subcarrier_abs = mem_offset + first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb]; + c16_t *srs_estimated_channel16 = &srs_est[subcarrier_abs]; + + for (int k = 0; k < M_sc_b_SRS; k++) { + if (k % fd_cdm == 0) { + ls_estimated = (c16_t){0, 0}; + uint16_t subcarrier_cdm = subcarrier; + + for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) { + c16_t generated_srs = srs_generated_signal[srs_symbol_offset + subcarrier_cdm]; + c16_t received_srs = srs_received_signal[srs_symbol_offset + subcarrier_cdm]; + // We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the real and imaginary parts of + // generated_srs. So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 + // bits. + ls_estimated = c16maddConjShift(generated_srs, received_srs, ls_estimated, nr_srs_info->srs_generated_signal_bits); + + // Subcarrier increment + subcarrier_cdm += K_TC; + if (subcarrier_cdm >= ofdm_symbol_size) { + subcarrier_cdm = subcarrier_cdm - ofdm_symbol_size; + } + } + } + + srs_ls_estimated_channel[srs_symbol_offset + subcarrier] = ls_estimated; + +#ifdef SRS_DEBUG + int subcarrier_log = subcarrier - subcarrier_offset; + if (subcarrier_log < 0) { + subcarrier_log = subcarrier_log + ofdm_symbol_size; + } + if (subcarrier_log % 12 == 0) { + LOG_I(NR_PHY, "------------------------------------ %d ------------------------------------\n", subcarrier_log / 12); + LOG_I(NR_PHY, "\t __genRe________genIm__|____rxRe_________rxIm__|____lsRe________lsIm_\n"); + } + LOG_I(NR_PHY, + "(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", + subcarrier_log, + srs_generated_signal[srs_symbol_offset + subcarrier].r, + srs_generated_signal[srs_symbol_offset + subcarrier].i, + srs_received_signal[srs_symbol_offset + subcarrier].r, + srs_received_signal[srs_symbol_offset + subcarrier].i, + ls_estimated.r, + ls_estimated.i); +#endif + + // Channel interpolation + if (srs_pdu->comb_size == 0) { + if (k == 0) { // First subcarrier case + // filt8_start is {12288,8192,4096,0,0,0,0,0} + c16multaddVectRealComplex(filt8_start, &ls_estimated, srs_estimated_channel16, 8); + } else if (k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases + // filt8_end is {4096,8192,12288,16384,0,0,0,0} + c16multaddVectRealComplex(filt8_end, &ls_estimated, srs_estimated_channel16, 8); + } else if (k % 2 == 1) { // 1st middle case + // filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0} + c16multaddVectRealComplex(filt8_middle2, &ls_estimated, srs_estimated_channel16, 8); + } else if (k % 2 == 0) { // 2nd middle case + // filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0} + c16multaddVectRealComplex(filt8_middle4, &ls_estimated, srs_estimated_channel16, 8); + srs_estimated_channel16 = &srs_est[subcarrier_abs]; + } + } else { + if (k == 0) { // First subcarrier case + // filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0} + c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16); + } else if (k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases + // filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0} + c16multaddVectRealComplex(filt16_end, &ls_estimated, srs_estimated_channel16, 16); + } else { // Middle case + // filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0} + c16multaddVectRealComplex(filt16_middle4, &ls_estimated, srs_estimated_channel16, 16); + srs_estimated_channel16 = &srs_est[subcarrier_abs]; + } + } + + // Subcarrier increment + subcarrier += K_TC; + if (subcarrier >= ofdm_symbol_size) { + subcarrier -= ofdm_symbol_size; + } + + subcarrier_abs += K_TC; + + } // for (int k = 0; k < M_sc_b_SRS; k++) + + memcpy(&srs_estimated_channel_freq[srs_symbol_offset], &srs_est[mem_offset], ofdm_symbol_size * sizeof(c16_t)); + + // Average srs channel estimates over multiple symbols + int16_t scale_factor = (1 << 15) / N_symb_SRS; + multadd_complex_vector_real_scalar(&srs_estimated_channel_freq[srs_symbol_offset], + scale_factor, + srs_estimated_channel_freq_avg, + ofdm_symbol_size); + +#ifdef SRS_DEBUG + subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][srs_symb]; + if (subcarrier >= ofdm_symbol_size) { + subcarrier -= ofdm_symbol_size; + } + + subcarrier_abs = first_subcarrier + nr_srs_info->k_0_p[p_index][srs_symb]; + + for (int k = 0; k < K_TC * M_sc_b_SRS; k++) { + int subcarrier_log = subcarrier - subcarrier_offset; + if (subcarrier_log < 0) { + subcarrier_log = subcarrier_log + ofdm_symbol_size; + } + + if (subcarrier_log % 12 == 0) { + LOG_I(NR_PHY, + "---------------------------- PRB %d, symbol %d -------------------------------\n", + subcarrier_log / 12, + srs_symb); + LOG_I(NR_PHY, "\t __lsRe__________lsIm__|____intRe_______intIm__|____noiRe_______noiIm__\n"); + } + + LOG_I(NR_PHY, + "(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n", + subcarrier_log, + srs_ls_estimated_channel[srs_symbol_offset + subcarrier].r, + srs_ls_estimated_channel[srs_symbol_offset + subcarrier].i, + srs_estimated_channel_freq[srs_symbol_offset + subcarrier_abs].r, + srs_estimated_channel_freq[srs_symbol_offset + subcarrier_abs].i, + srs_received_noise[srs_symbol_offset + subcarrier].r, + srs_received_noise[srs_symbol_offset + subcarrier].i); + + // Subcarrier increment + subcarrier++; + if (subcarrier >= ofdm_symbol_size) { + subcarrier -= ofdm_symbol_size; + } + subcarrier_abs++; + } +#endif } - signal_power = max(signal_power / (frame_parms->nb_antennas_rx * N_ap), 1); - noise_power = max(noise_power / (frame_parms->nb_antennas_rx), 1); - if (signal_power == 0) { + + // Convert to time domain + int16_t ofdm_symbol_size_half = ofdm_symbol_size >> 1; + int16_t ofdm_os_size = NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size; + int16_t ofdm_os_size_half = ofdm_os_size >> 1; + int16_t start_offset = ofdm_os_size - ofdm_symbol_size_half; + + c16_t chF_interpol[ofdm_os_size] __attribute__((aligned(32))); + memset(chF_interpol, 0, sizeof(chF_interpol)); + + // Place SRS channel estimates in FFT shifted format for oversampling + memcpy(&chF_interpol[0], &srs_estimated_channel_freq_avg[ofdm_symbol_size_half], ofdm_symbol_size_half * sizeof(c16_t)); + memcpy(&chF_interpol[start_offset], &srs_estimated_channel_freq_avg[0], ofdm_symbol_size_half * sizeof(c16_t)); + + // Convert to time domain oversampled + freq2time(ofdm_os_size, (int16_t *)chF_interpol, (int16_t *)srs_estimated_channel_time); + + // Do FFT shift + memcpy(srs_estimated_channel_time_shifted, &srs_estimated_channel_time[ofdm_os_size_half], ofdm_os_size_half * sizeof(c16_t)); + + memcpy(&srs_estimated_channel_time_shifted[ofdm_os_size_half], srs_estimated_channel_time, ofdm_os_size_half * sizeof(c16_t)); + + // Compute wideband SNR on the symbol 0 + int tot_subcarriers = m_SRS_b * NR_NB_SC_PER_RB; + + uint16_t subcarrier_abs = first_subcarrier + nr_srs_info->k_0_p[p_index][0]; + if (subcarrier_abs + tot_subcarriers < ofdm_symbol_size_half) { + *signal_power = signal_energy_nodc(&srs_estimated_channel_freq[subcarrier_abs], tot_subcarriers) / tot_subcarriers; + } else { + int size1 = ofdm_symbol_size_half - subcarrier_abs; + int size2 = tot_subcarriers - size1; + uint64_t signal_power_p1 = signal_energy_nodc(&srs_estimated_channel_freq[subcarrier_abs], size1) * size1; + uint64_t signal_power_p2 = signal_energy_nodc(&srs_estimated_channel_freq[ofdm_symbol_size_half], size2) * size2; + *signal_power = (signal_power_p1 + signal_power_p2) / tot_subcarriers; + } + + if (*signal_power == 0) { LOG_W(NR_PHY, "Received SRS signal power is 0\n"); return -1; } - *snr = dB_fixed(signal_power) - dB_fixed(noise_power); - // Compute SNR per RB - uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[0][0]; - for (int rb = 0; rb < m_SRS_b; rb++) { - if (subcarrier >= frame_parms->ofdm_symbol_size) { - subcarrier -= frame_parms->ofdm_symbol_size; + subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; + if (subcarrier >= ofdm_symbol_size) { + subcarrier -= ofdm_symbol_size; + } + + if (p_index == 0) { + if (subcarrier + tot_subcarriers < ofdm_symbol_size) { + *noise_power = signal_energy_nodc(&srs_received_noise[subcarrier], tot_subcarriers) / tot_subcarriers; + } else { + int size1 = ofdm_symbol_size - subcarrier; + int size2 = tot_subcarriers - size1; + uint64_t noise_power_p1 = signal_energy_nodc(&srs_received_noise[subcarrier], size1) * size1; + uint64_t noise_power_p2 = signal_energy_nodc(&srs_received_noise[0], size2) * size2; + *noise_power = (noise_power_p1 + noise_power_p2) / tot_subcarriers; } - uint32_t noise_power_per_rb = 0; - for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { - if (subcarrier + NR_NB_SC_PER_RB < frame_parms->ofdm_symbol_size) { - noise_power_per_rb += signal_energy_nodc(&srs_received_noise[ant][subcarrier], NR_NB_SC_PER_RB); - } else { - int size1 = frame_parms->ofdm_symbol_size - subcarrier; - int size2 = NR_NB_SC_PER_RB - size1; - uint32_t noise_power_per_rb1 = signal_energy_nodc(&srs_received_noise[ant][subcarrier], size1) * size1; - uint32_t noise_power_per_rb2 = signal_energy_nodc(&srs_received_noise[ant][0], size2) * size2; - noise_power_per_rb += (noise_power_per_rb1 + noise_power_per_rb2) / NR_NB_SC_PER_RB; + } + + // Compute SNR per RB for port 0 and symbol 0 + if (p_index == 0) { + subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0]; + for (int rb = 0; rb < m_SRS_b; rb++) { + if (subcarrier >= ofdm_symbol_size) { + subcarrier -= ofdm_symbol_size; } - } - noise_power_per_rb = max(noise_power_per_rb / (frame_parms->nb_antennas_rx), 1); - snr_per_rb[rb] = dB_fixed(signal_power) - dB_fixed(noise_power_per_rb); - subcarrier += NR_NB_SC_PER_RB; + if (subcarrier + NR_NB_SC_PER_RB < ofdm_symbol_size) { + noise_power_per_rb[rb] += signal_energy_nodc(&srs_received_noise[subcarrier], NR_NB_SC_PER_RB); + } else { + int size1 = ofdm_symbol_size - subcarrier; + int size2 = NR_NB_SC_PER_RB - size1; + uint32_t noise_power_per_rb1 = signal_energy_nodc(&srs_received_noise[subcarrier], size1) * size1; + uint32_t noise_power_per_rb2 = signal_energy_nodc(&srs_received_noise[0], size2) * size2; + noise_power_per_rb[rb] += (noise_power_per_rb1 + noise_power_per_rb2) / NR_NB_SC_PER_RB; + } + noise_power_per_rb[rb] = max(noise_power_per_rb[rb], 1); + subcarrier += NR_NB_SC_PER_RB; #ifdef SRS_DEBUG - LOG_I(NR_PHY, "[RB %3i] noise_power_per_rb = %i, snr_per_rb = %i dB\n", rb, noise_power_per_rb, snr_per_rb[rb]); + LOG_I(NR_PHY, + "[RB %3i] noise_power_per_rb = %i, SNR_per_rb = %i dB\n", + rb, + noise_power_per_rb[rb], + dB_fixed(*signal_power) - dB_fixed(noise_power_per_rb[rb])); #endif + } } #ifdef SRS_DEBUG - LOG_I(NR_PHY, "signal_power = %i dB, noise_power = %i dB, SNR = %i dB\n", dB_fixed(signal_power), dB_fixed(noise_power), *snr); + int32_t signal_power_dB = dB_fixed(*signal_power); + int32_t noise_power_dB = dB_fixed(*noise_power); + LOG_I(NR_PHY, + "signal_power = %i dB, noise_power = %i dB, SNR = %i dB\n", + signal_power_dB, + noise_power_dB, + signal_power_dB - noise_power_dB); #endif return 0; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index 7e0a2a97bd..21ecb39427 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -59,8 +59,13 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB); void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]); -int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, - const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]); +void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size, + const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], + uint8_t ant, + uint8_t N_ap, + uint32_t samples_per_frame, + uint16_t *timing_advance_offset, + int16_t *timing_advance_offset_nsec); void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *frame_parms, @@ -70,21 +75,22 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, unsigned char symbol, uint32_t nb_re_pusch); -int nr_srs_channel_estimation( - const PHY_VARS_gNB *gNB, - const int frame, - const int slot, - const nfapi_nr_srs_pdu_t *srs_pdu, - const nr_srs_info_t *nr_srs_info, - const c16_t **srs_generated_signal, - c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], - c16_t srs_received_noise[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], - c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports] - [gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], - c16_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - c16_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], - int16_t *snr_per_rb, - int8_t *snr); +int nr_srs_channel_estimation(int ant, + int p_index, + uint16_t ofdm_symbol_size, + uint16_t first_carrier_offset, + uint8_t N_symb_SRS, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const c16_t *srs_generated_signal, + c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS], + c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS], + c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS], + c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], + c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], + uint32_t *signal_power, + uint32_t *noise_power, + int16_t *noise_power_per_rb); void nr_freq_equalization(NR_DL_FRAME_PARMS *frame_parms, c16_t *rxdataF_comp, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 2df2df8eb0..12bff45dee 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -61,9 +61,13 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE]; nr_fill_reg_list(reg_list, pdcch_pdu_rel15); // compute rb_offset and n_prb based on frequency allocation - int rb_offset; - int n_rb; - get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); + int n_rb, cset_start; + get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource, &n_rb, &cset_start); + int additional_offset = 0; + // first common RB of the first group of 6 PRBs has common RB index equal to 6 * ⌈BWP_start / 6⌉ + if (pdcch_pdu_rel15->CoreSetType == 1) + additional_offset = (pdcch_pdu_rel15->BWPStart + 5) / 6 * 6 - pdcch_pdu_rel15->BWPStart; + int rb_offset = cset_start + additional_offset; uint16_t cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; int idx1 = pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols; int idx2 = (((n_rb + rb_offset + pdcch_pdu_rel15->BWPStart) * 3) + 15) & ~15; @@ -83,7 +87,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, int bitmap = SL_to_bitmap(cset_start_symb, pdcch_pdu_rel15->DurationSymbols); int beam_nb = beam_index_allocation(gNB->enable_analog_das, dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx, - &gNB->gNB_config.analog_beamforming_ve, &gNB->common_vars, slot, frame_parms->symbols_per_slot, @@ -195,7 +198,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2 int dmrs_idx; if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) - dmrs_idx = (reg_list[d][reg_count] + pdcch_pdu_rel15->BWPStart) * 3; + dmrs_idx = (reg_list[d][reg_count] + pdcch_pdu_rel15->BWPStart + rb_offset) * 3; else dmrs_idx = (reg_list[d][reg_count] + rb_offset) * 3; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 8df7b4814c..b8663aa435 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -681,7 +681,6 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC int bitmap = SL_to_bitmap(rel15->StartSymbolIndex, rel15->NrOfSymbols); int beam_nb = beam_index_allocation(gNB->enable_analog_das, pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, - &gNB->gNB_config.analog_beamforming_ve, &gNB->common_vars, slot, frame_parms->symbols_per_slot, diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 823af815d3..e42c02953c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -103,7 +103,6 @@ prach_item_t *nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_n int bitmap = SL_to_bitmap(start_symb, n_symb); prach->beams[i] = beam_index_allocation(gNB->enable_analog_das, fapi_beam_idx, - &gNB->gNB_config.analog_beamforming_ve, &gNB->common_vars, Slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, @@ -362,7 +361,7 @@ static void rx_nr_prach_ru_internal(prach_item_t *p, // Fixme: slot or slot makes no sense ??? int slot2 = p->prach_sequence_length ? p->slot : p->slot; int idx = aa + beam_id * p->nb_rx; - c16_t *prach = (c16_t *)&rxdata[idx][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - N_TA_offset]; + c16_t *prach = (c16_t *)&rxdata[idx][get_samples_slot_timestamp(fp, slot2) + sample_offset_slot - N_TA_offset]; // do DFT c16_t *prach2 = prach + Ncp; diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 29fca5975e..29ae5bb612 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -231,6 +231,22 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], c16_t srs_received_noise[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)]); +void nr_srs_rx_procedures(PHY_VARS_gNB *gNB, + int frame_rx, + int slot_rx, + uint8_t nb_antennas_rx, + uint8_t N_ap, + uint8_t N_symb_SRS, + uint16_t ofdm_symbol_size, + NR_gNB_SRS_t *srs, + nr_srs_info_t *nr_srs_info, + int *srs_est, + c16_t srs_estimated_channel_freq[][N_ap][ofdm_symbol_size * N_symb_SRS], + c16_t srs_estimated_channel_time[][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], + int16_t *snr_per_rb, + uint16_t *timing_advance_offset, + int16_t *timing_advance_offset_nsec); + int get_nr_prach_duration(uint8_t prach_format); void free_nr_prach_entry(prach_list_t *, prach_item_t *); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 06aef61935..b963b7d970 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -158,7 +158,6 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t int bitmap = SL_to_bitmap(ulsch_pdu->start_symbol_index, ulsch_pdu->nr_of_symbols); ulsch->beam_nb = beam_index_allocation(gNB->enable_analog_das, fapi_beam_idx, - &gNB->gNB_config.analog_beamforming_ve, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 2a3987e755..8e2076df2f 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -71,7 +71,6 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t int bitmap = SL_to_bitmap(pucch_pdu->start_symbol_index, pucch_pdu->nr_of_symbols); pucch->beam_nb = beam_index_allocation(gNB->enable_analog_das, fapi_beam_idx, - &gNB->gNB_config.analog_beamforming_ve, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 3da018bf84..5d84c11c99 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -56,11 +56,11 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu srs->active = true; srs->beam_nb = 0; if (gNB->common_vars.beam_id) { - int bitmap = SL_to_bitmap(srs_pdu->time_start_position, 1 << srs_pdu->num_symbols); + const uint8_t l0 = gNB->frame_parms.symbols_per_slot - 1 - srs_pdu->time_start_position; + int bitmap = SL_to_bitmap(l0, 1 << srs_pdu->num_symbols); int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; srs->beam_nb = beam_index_allocation(gNB->enable_analog_das, fapi_beam_idx, - &gNB->gNB_config.analog_beamforming_ve, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, @@ -85,7 +85,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; const uint16_t n_symbols = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot; // number of symbols until this slot - const uint8_t l0 = srs_pdu->time_start_position; // starting symbol in this slot + const uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_pdu->time_start_position; // starting symbol in this slot const uint64_t symbol_offset = (n_symbols + l0) * frame_parms->ofdm_symbol_size; const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB; diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c index 4a884b964b..6f3466e436 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c @@ -21,7 +21,6 @@ #include "PHY/types.h" #include "PHY/defs_nr_UE.h" -#include "PHY/phy_extern_nr_ue.h" void phy_adjust_gain_nr (PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 4c8c57d9fd..b04f595481 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -34,7 +34,6 @@ #include "executables/nr-softmodem-common.h" #include "PHY/defs_nr_UE.h" #include "PHY/INIT/nr_phy_init.h" -#include "PHY/phy_extern_nr_ue.h" #include "common/utils/LOG/log.h" #include "PHY/sse_intrin.h" #include "SCHED_NR_UE/defs.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index 26cad50f12..b2e43b3c16 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -35,7 +35,6 @@ #include "executables/nr-softmodem-common.h" #include "nr_transport_proto_ue.h" -#include "PHY/phy_extern_nr_ue.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "common/utils/nr/nr_common.h" #include "PHY/NR_UE_ESTIMATION/filt16a_32.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index f4ab076921..822389ebdc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -204,6 +204,7 @@ static void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz, c16_t dl_ch_estimates_ext[][arraySz], NR_DL_FRAME_PARMS *frame_parms, uint8_t *coreset_freq_dom, + uint32_t rb_offset, uint32_t coreset_nbr_rb, uint32_t n_BWP_start) { @@ -250,7 +251,7 @@ static void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz, continue; } for (int rb = 0; rb < 6; rb++) { - int c_rb = rb_group * 6 + rb; + int c_rb = rb_group * 6 + rb + rb_offset; c16_t *rxF = NULL; if ((frame_parms->N_RB_DL & 1) == 0) { if ((c_rb + n_BWP_start) < frame_parms->N_RB_DL / 2) @@ -338,10 +339,9 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue, fapi_nr_coreset_t *coreset = &phy_pdcch_config->pdcch_config[ss_idx].coreset; int32_t pdcch_est_size = ceil_mod(fp->ofdm_symbol_size + LTE_CE_FILTER_LENGTH, 16); __attribute__((aligned(16))) c16_t pdcch_dl_ch_estimates[fp->nb_antennas_rx][pdcch_est_size]; - int n_rb; - int rb_offset; - get_coreset_rballoc(coreset->frequency_domain_resource, &n_rb, &rb_offset); - + int n_rb, cset_start; + get_coreset_rballoc(coreset->frequency_domain_resource, &n_rb, &cset_start); + int rb_offset = cset_start + coreset->rb_offset; unsigned short scrambling_id = coreset->pdcch_dmrs_scrambling_id; int dmrs_ref = 0; if (coreset->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) @@ -376,6 +376,7 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue, pdcch_dl_ch_estimates_ext, fp, coreset->frequency_domain_resource, + coreset->rb_offset, n_rb, phy_pdcch_config->pdcch_config[ss_idx].BWPStart); @@ -509,10 +510,8 @@ void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc, uint8_t unused_start_symb[NR_SYMBOLS_PER_SLOT] = {0}; const int num_monitoring_occ = get_pdcch_mon_occasions_slot(rel15, unused_start_symb); const int llr_stride = llr_size / rel15->coreset.duration; - - int n_rb; - int rb_offset; - get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &rb_offset); + int n_rb, cset_start; + get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start); for (int m = 0; m < num_monitoring_occ; m++) { /// PDCCH/DCI e-sequence (input to rate matching). @@ -643,9 +642,9 @@ static void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, .ss_type = rel15->ss_type_options[k], .coreset_type = rel15->coreset.CoreSetType, }; - int n_rb, rb_offset; - get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &rb_offset); - dci->cset_start = rel15->BWPStart + rb_offset; + int n_rb, cset_start; + get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start); + dci->cset_start = rel15->BWPStart + cset_start + rel15->coreset.rb_offset; dci->payloadSize = dci_length; memcpy(dci->payloadBits, dci_estimation, (dci_length + 7) / 8); dci_ind->number_of_dcis++; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index e6b4503e1b..be71e435a0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -25,7 +25,6 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "PHY/defs_nr_UE.h" #include "SCHED_NR_UE/harq_nr.h" -#include "PHY/phy_extern_nr_ue.h" #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c index f9047aedd0..619262c746 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c @@ -324,7 +324,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int32_t sync_pos = -1; // sync_pos_frame = -1; int32_t metric_tdd_ncp = 0; - uint8_t phase_tdd_ncp; + uint8_t phase_tdd_ncp = 0; double im, re; int ret = -1; uint16_t rx_slss_id = 65535; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ntn_l1.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ntn_l1.c new file mode 100644 index 0000000000..deae817a36 --- /dev/null +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ntn_l1.c @@ -0,0 +1,189 @@ +/* + * 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 "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" + +void fix_ntn_epoch_hfn(PHY_VARS_NR_UE *UE, int hfn, int frame) +{ + if (!UE->nrUE_config.ntn_config.is_targetcell) + return; + UE->nrUE_config.ntn_config.is_targetcell = false; + + const int epoch_frame = UE->nrUE_config.ntn_config.epoch_sfn; + const int diff1 = (frame - epoch_frame + 1024) % 1024; + const int diff2 = (epoch_frame - frame + 1024) % 1024; + + int *epoch_hfn = &UE->nrUE_config.ntn_config.epoch_hfn; + if (diff1 < diff2) { // epoch_frame in the past + LOG_I(PHY, "epoch is %d frames in the past\n", diff1); + if (epoch_frame <= frame) + *epoch_hfn = hfn; + else + *epoch_hfn = hfn - 1; + } else { // epoch_frame in the future + LOG_I(PHY, "epoch is %d frames in the future\n", diff2); + if (epoch_frame >= frame) + *epoch_hfn = hfn; + else + *epoch_hfn = hfn + 1; + } + LOG_I(PHY, "setting epoch_hfn = %d\n", *epoch_hfn); +} + +// calculate TA and Doppler based on the NTN-Config, if abs_subframe_tx < 0 then apply only Doppler +void apply_ntn_timing_advance_and_doppler(PHY_VARS_NR_UE *UE, const NR_DL_FRAME_PARMS *fp, int abs_subframe_tx) +{ + const fapi_nr_ntn_config_t *ntn_config_params = &UE->nrUE_config.ntn_config; + + // Handle terrestrial networks + if (ntn_config_params->cell_specific_k_offset == 0) { + if (abs_subframe_tx >= 0) + UE->timing_advance_ntn = 0; + UE->dl_Doppler_shift = 0; + UE->ul_Doppler_shift = 0; + return; + } + + const int abs_subframe_epoch = ntn_config_params->epoch_subframe + + ntn_config_params->epoch_sfn * 10 + + ntn_config_params->epoch_hfn * 10240; + const int ms_since_epoch = abs_subframe_tx < 0 ? 0 : abs_subframe_tx - abs_subframe_epoch; + + const position_t pos_sat_0 = ntn_config_params->pos_sat_0; + const position_t vel_sat_0 = ntn_config_params->vel_sat_0; + + position_t pos_sat; + position_t vel_sat; + + const double omega = ntn_config_params->omega; + if (omega) { + const double cos_wt = cos(omega * ms_since_epoch); + const double sin_wt = sin(omega * ms_since_epoch); + + const position_t pos_sat_90 = ntn_config_params->pos_sat_90; + pos_sat = (position_t){pos_sat_0.X * cos_wt + pos_sat_90.X * sin_wt, + pos_sat_0.Y * cos_wt + pos_sat_90.Y * sin_wt, + pos_sat_0.Z * cos_wt + pos_sat_90.Z * sin_wt}; + + const position_t vel_sat_90 = ntn_config_params->vel_sat_90; + vel_sat = (position_t){vel_sat_0.X * cos_wt + vel_sat_90.X * sin_wt, + vel_sat_0.Y * cos_wt + vel_sat_90.Y * sin_wt, + vel_sat_0.Z * cos_wt + vel_sat_90.Z * sin_wt}; + } else { + pos_sat = (position_t){pos_sat_0.X + vel_sat_0.X * ms_since_epoch / 1000, + pos_sat_0.Y + vel_sat_0.Y * ms_since_epoch / 1000, + pos_sat_0.Z + vel_sat_0.Z * ms_since_epoch / 1000}; + vel_sat = vel_sat_0; + } + + position_t pos_ue = {0}; + get_position_coordinates(UE->Mod_id, &pos_ue); + + // calculate directional vector from SAT to UE + const position_t dir_sat_ue = {pos_ue.X - pos_sat.X, pos_ue.Y - pos_sat.Y, pos_ue.Z - pos_sat.Z}; + + // calculate distance between SAT and UE + const double distance = sqrt(dir_sat_ue.X * dir_sat_ue.X + dir_sat_ue.Y * dir_sat_ue.Y + dir_sat_ue.Z * dir_sat_ue.Z); + + // calculate projected velocity from SAT towards UE + const double vel_sat_ue = (vel_sat.X * dir_sat_ue.X + vel_sat.Y * dir_sat_ue.Y + vel_sat.Z * dir_sat_ue.Z) / distance; + + // calculate DL Doppler shift (moving source) + const double dl_Doppler_shift = (vel_sat_ue / (SPEED_OF_LIGHT - vel_sat_ue)) * fp->dl_CarrierFreq; + + // calculate UL Doppler shift (moving target) + const double ul_Doppler_shift = (vel_sat_ue / SPEED_OF_LIGHT) * fp->ul_CarrierFreq; + + // calculate round-trip-time (factor 2) between SAT and UE in ms (factor 1000) + const double N_UE_TA_adj = 2000 * distance / SPEED_OF_LIGHT; + + const double N_common_ta_adj = ntn_config_params->N_common_ta_adj; + const double N_common_ta_drift = ntn_config_params->N_common_ta_drift; + const double N_common_ta_drift_variant = ntn_config_params->N_common_ta_drift_variant; + + if (abs_subframe_tx >= 0) { + UE->timing_advance_ntn = (N_UE_TA_adj + N_common_ta_adj + N_common_ta_drift * ms_since_epoch / 1e6 + + N_common_ta_drift_variant * ((int64_t)ms_since_epoch * ms_since_epoch) / 1e9) + * fp->samples_per_subframe; + } + + UE->freq_offset -= dl_Doppler_shift - UE->dl_Doppler_shift; + UE->dl_Doppler_shift = dl_Doppler_shift; + UE->ul_Doppler_shift = ul_Doppler_shift; + + if (abs_subframe_tx < 0) { + LOG_I(PHY, + "satellite velocity towards UE = %f m/s, DL Doppler shift = %f kHz, UL Doppler shift = %f kHz\n", + vel_sat_ue, + dl_Doppler_shift / 1000, + ul_Doppler_shift / 1000); + } +} + +// apply values based on the NTN-Config +void apply_ntn_config(PHY_VARS_NR_UE *UE, + NR_DL_FRAME_PARMS *fp, + int hfn_rx, + int frame_rx, + int slot_rx, + int *duration_rx_to_tx, + int *timing_advance, + int *ntn_koffset, + bool *ntn_targetcell) +{ + // return if there is no pending update + if (!UE->nrUE_config.ntn_config.params_changed) + return; + + *ntn_targetcell = UE->nrUE_config.ntn_config.is_targetcell; + + // skip update if it is for the target cell + if (UE->nrUE_config.ntn_config.is_targetcell) + return; + + UE->nrUE_config.ntn_config.params_changed = false; + + const fapi_nr_ntn_config_t *ntn_config_params = &UE->nrUE_config.ntn_config; + + const int mu = fp->numerology_index; + const int koffset = ntn_config_params->cell_specific_k_offset; + + *duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX + (koffset << mu); + if (koffset > *ntn_koffset) + *timing_advance += get_samples_slot_duration(fp, slot_rx, (koffset - *ntn_koffset) << mu); + else if (koffset < *ntn_koffset) + *timing_advance -= get_samples_slot_duration(fp, slot_rx, (*ntn_koffset - koffset) << mu); + *ntn_koffset = koffset; + + const int abs_subframe_tx = 10240 * hfn_rx + 10 * frame_rx + ((slot_rx + *duration_rx_to_tx) >> mu); + apply_ntn_timing_advance_and_doppler(UE, fp, abs_subframe_tx); + + LOG_I(PHY, + "k_offset: %dms, N_Common_Ta: %fms, drift: %fµs/s, variant: %fµs/s², " + "timing_advance_ntn: %d samples, DL Doppler shift: %fkHz, UL Doppler shift: %fkHz\n", + koffset << mu, + ntn_config_params->N_common_ta_adj, + ntn_config_params->N_common_ta_drift, + ntn_config_params->N_common_ta_drift_variant, + UE->timing_advance_ntn, + UE->dl_Doppler_shift / 1000, + UE->ul_Doppler_shift / 1000); +} diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 00130b3642..8d3ac6db21 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -31,7 +31,6 @@ */ #include "PHY/defs_nr_UE.h" #include "PHY/CODING/coding_extern.h" -#include "PHY/phy_extern_nr_ue.h" #include "PHY/sse_intrin.h" #include "PHY/INIT/nr_phy_init.h" #include "openair1/SCHED_NR_UE/defs.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 9405315e04..05a251d999 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -58,34 +58,19 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config; fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu; - uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found; - uint16_t rootSequenceIndex, prach_fmt_id, NCS, preamble_offset = 0; - const uint16_t *prach_root_sequence_map; - uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start=INT16_MAX, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx; - c16_t prach[(4688 + 4 * 24576) * 2] __attribute__((aligned(32))) = {0}; - c16_t prachF_tmp[(4688 + 4 * 24576) * 4] __attribute__((aligned(32))) = {0}; - - int Ncp = 0; - int prach_start, prach_sequence_length, prach_len, dftlen, mu, n_ra_prb, k, prachStartSymbol; - - fd_occasion = prach_pdu->num_ra; - prach_len = 0; - dftlen = 0; - first_nonzero_root_idx = 0; - int16_t amp = prach_pdu->prach_tx_power; - c16_t *prachF = prachF_tmp; - Mod_id = ue->Mod_id; - prach_sequence_length = nrUE_config->prach_config.prach_sequence_length; - N_ZC = (prach_sequence_length == 0) ? 839:139; - mu = nrUE_config->prach_config.prach_sub_c_spacing; - restricted_set = prach_pdu->restricted_set; - rootSequenceIndex = prach_pdu->root_seq_id; - n_ra_prb = nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1,//prach_pdu->freq_msg1; - NCS = prach_pdu->num_cs; - prach_fmt_id = prach_pdu->prach_format; - preamble_index = prach_pdu->ra_PreambleIndex; - k = 12*n_ra_prb - 6*fp->N_RB_UL; - prachStartSymbol = prach_pdu->prach_start_symbol; + const int fd_occasion = prach_pdu->num_ra; + const int16_t amp = prach_pdu->prach_tx_power; + const int prach_sequence_length = nrUE_config->prach_config.prach_sequence_length; + const int N_ZC = (prach_sequence_length == 0) ? 839 : 139; + const int mu = nrUE_config->prach_config.prach_sub_c_spacing; + const int restricted_set = prach_pdu->restricted_set; + const int rootSequenceIndex = prach_pdu->root_seq_id; + const int n_ra_prb = nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1; // prach_pdu->freq_msg1; + const int NCS = prach_pdu->num_cs; + const int prach_fmt_id = prach_pdu->prach_format; + const int preamble_index = prach_pdu->ra_PreambleIndex; + int k = 12 * n_ra_prb - 6 * fp->N_RB_UL; + const int prachStartSymbol = prach_pdu->prach_start_symbol; LOG_D(PHY,"Generate NR PRACH %d.%d\n", frame, slot); @@ -97,6 +82,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t nrUE_config->prach_config.root_seq_computed = 1; } + int prach_start; if (prachStartSymbol == 0) { prach_start = 0; } else if (fp->slots_per_subframe == 1) { @@ -122,29 +108,30 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t * NOTE: Restricted set type B is not implemented *************************************************************************/ - prach_root_sequence_map = (prach_sequence_length == 0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc; - + const uint16_t *prach_root_sequence_map = + (prach_sequence_length == 0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc; + int preamble_offset, preamble_shift = 0, first_nonzero_root_idx = 0; if (restricted_set == 0) { // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index - preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS))); + preamble_offset = NCS == 0 ? preamble_index : preamble_index / (N_ZC / NCS); // This is the \nu corresponding to the preamble index - preamble_shift = (NCS==0)? 0 : (preamble_index % (N_ZC/NCS)); + preamble_shift = NCS == 0 ? 0 : preamble_index % (N_ZC / NCS); preamble_shift *= NCS; } else { // This is the high-speed case - #ifdef NR_PRACH_DEBUG - LOG_I(PHY, "PRACH [UE %d] High-speed mode, NCS %d\n", Mod_id, NCS); - #endif +#ifdef NR_PRACH_DEBUG + LOG_I(PHY, "PRACH [UE %d] High-speed mode, NCS %d\n", ue->Mod_id, NCS); +#endif - not_found = 1; uint16_t nr_du[NR_PRACH_SEQ_LEN_L - 1]; nr_fill_du(N_ZC, prach_root_sequence_map, nr_du); - preamble_index0 = preamble_index; + int preamble_index0 = preamble_index; // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this // preamble index and find the corresponding cyclic shift preamble_offset = 0; // relative rootSequenceIndex; - while (not_found == 1) { + bool not_found = true; + while (not_found) { // current root depending on rootSequenceIndex and preamble_offset int index = (rootSequenceIndex + preamble_offset) % N_ZC; uint16_t n_group_ra = 0; @@ -157,8 +144,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t DevAssert( index < sizeof(prach_root_sequence_map_abc) / sizeof(prach_root_sequence_map_abc[0]) ); } - u = prach_root_sequence_map[index]; - + int u = prach_root_sequence_map[index]; + int n_shift_ra, d_start = INT16_MAX, n_shift_ra_bar; if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) { n_shift_ra = nr_du[u]/NCS; d_start = (nr_du[u]<<1) + (n_shift_ra * NCS); @@ -175,13 +162,12 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t } // This is the number of cyclic shifts for the current root u - numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar; - + int numshift = (n_shift_ra * n_group_ra) + n_shift_ra_bar; if (numshift>0 && preamble_index0==preamble_index) first_nonzero_root_idx = preamble_offset; if (preamble_index0 < numshift) { - not_found = 0; + not_found = false; preamble_shift = (d_start * (preamble_index0/n_shift_ra)) + ((preamble_index0%n_shift_ra)*NCS); } else { // skip to next rootSequenceIndex and recompute parameters @@ -193,23 +179,22 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t // now generate PRACH signal #ifdef NR_PRACH_DEBUG - if (NCS>0) - LOG_I(PHY, "PRACH [UE %d] generate PRACH in frame.slot %d.%d for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d msg1 frequency start %d\n", - Mod_id, - frame, - slot, - rootSequenceIndex, - preamble_index, - prachfmt[prach_fmt_id], - NCS, - N_ZC, - preamble_offset, - preamble_shift, - n_ra_prb); - #endif - - // nsymb = (frame_parms->Ncp==0) ? 14:12; - // subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*slot*nsymb; + if (NCS > 0) + LOG_I(PHY, + "PRACH [UE %d] generate PRACH in frame.slot %d.%d for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d " + "(N_ZC %d): Preamble_offset %d, Preamble_shift %d msg1 frequency start %d\n", + ue->Mod_id, + frame, + slot, + rootSequenceIndex, + preamble_index, + prachfmt[prach_fmt_id], + NCS, + N_ZC, + preamble_offset, + preamble_shift, + n_ra_prb); +#endif const unsigned int K = get_prach_K(prach_sequence_length, prach_fmt_id, fp->numerology_index, mu); const uint8_t kbar = get_PRACH_k_bar(mu, fp->numerology_index); @@ -223,7 +208,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t LOG_I(PHY, "PRACH [UE %d] in frame.slot %d.%d, placing PRACH in position %d, Msg1/MsgA-Preamble frequency start %d (k1 %d), " "preamble_offset %d, first_nonzero_root_idx %d, preambleIndex = %d\n", - Mod_id, + ue->Mod_id, frame, slot, k * 2, @@ -234,155 +219,96 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t prach_pdu->ra_PreambleIndex); // Ncp and dftlen here is given in terms of T_s wich is 30.72MHz sampling + int dftlen, Ncp; if (prach_sequence_length == 0) { - switch (prach_fmt_id) { - case 0: - Ncp = 3168; - dftlen = 24576; - break; - - case 1: - Ncp = 21024; - dftlen = 24576; - break; - - case 2: - Ncp = 4688; - dftlen = 24576; - break; - - case 3: - Ncp = 3168; - dftlen = 6144; - break; - - default: - AssertFatal(1 == 0, "Illegal PRACH format %d for sequence length 839\n", prach_fmt_id); - break; - } + AssertFatal(prach_fmt_id >= 0 && prach_fmt_id <= 3, "Unknown PRACH format ID %d for sequence length 839\n", prach_fmt_id); + const int ncp[4] = {3168, 21024, 4688, 3168}; + const int dft[4] = {24576, 24576, 24576, 6144}; + Ncp = ncp[prach_fmt_id]; + dftlen = dft[prach_fmt_id]; } else { - switch (prach_fmt_id) { - case 4: //A1 - Ncp = 288 >> mu; - break; - - case 5: //A2 - Ncp = 576 >> mu; - break; - - case 6: //A3 - Ncp = 864 >> mu; - break; - - case 7: //B1 - Ncp = 216 >> mu; - break; - - /* - case 4: //B2 - Ncp = 360 >> mu; - break; - - case 5: //B3 - Ncp = 504 >> mu; - break; - */ - - case 8: //B4 - Ncp = 936 >> mu; - break; - - case 9: //C0 - Ncp = 1240 >> mu; - break; - - case 10: //C2 - Ncp = 2048 >> mu; - break; - - default: - AssertFatal(1==0,"Unknown PRACH format ID %d\n", prach_fmt_id); - break; - } + AssertFatal(prach_fmt_id >= 4 && prach_fmt_id <= 10, "Unknown PRACH format ID %d\n", prach_fmt_id); + const int ncp[7] = {288, 576, 864, 216, 936, 1240, 2048}; + Ncp = ncp[prach_fmt_id - 4] >> mu; dftlen = 2048 >> mu; } - //actually what we should be checking here is how often the current prach crosses a 0.5ms boundary. I am not quite sure for which paramter set this would be the case, so I will ignore it for now and just check if the prach starts on a 0.5ms boundary - if(fp->numerology_index == 0) { + // actually what we should be checking here is how often the current prach crosses a 0.5ms boundary. I am not quite sure for + // which paramter set this would be the case, so I will ignore it for now and just check if the prach starts on a 0.5ms boundary + if (fp->numerology_index == 0) { if (prachStartSymbol == 0 || prachStartSymbol == 7) Ncp += 16; - } - else { - if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) + } else { + if (slot % (fp->slots_per_subframe / 2) == 0 && prachStartSymbol == 0) Ncp += 16; } - switch(fp->samples_per_subframe) { - case 7680: - // 5 MHz @ 7.68 Ms/s - Ncp >>= 2; - dftlen >>= 2; - break; + switch (fp->samples_per_subframe) { + case 7680: + // 5 MHz @ 7.68 Ms/s + Ncp >>= 2; + dftlen >>= 2; + break; - case 15360: - // 10, 15 MHz @ 15.36 Ms/s - Ncp >>= 1; - dftlen >>= 1; - break; + case 15360: + // 10, 15 MHz @ 15.36 Ms/s + Ncp >>= 1; + dftlen >>= 1; + break; - case 23040: - // 20 MHz @ 23.04 Ms/s - Ncp = (Ncp * 3) / 4; - dftlen = (dftlen * 3) / 4; - break; + case 23040: + // 20 MHz @ 23.04 Ms/s + Ncp = (Ncp * 3) / 4; + dftlen = (dftlen * 3) / 4; + break; - case 30720: - // 20, 25, 30 MHz @ 30.72 Ms/s - break; + case 30720: + // 20, 25, 30 MHz @ 30.72 Ms/s + break; - case 46080: - // 40 MHz @ 46.08 Ms/s - Ncp = (Ncp*3)/2; - dftlen = (dftlen*3)/2; - break; + case 46080: + // 40 MHz @ 46.08 Ms/s + Ncp = (Ncp * 3) / 2; + dftlen = (dftlen * 3) / 2; + break; - case 61440: - // 40, 50, 60 MHz @ 61.44 Ms/s - Ncp <<= 1; - dftlen <<= 1; - break; + case 61440: + // 40, 50, 60 MHz @ 61.44 Ms/s + Ncp <<= 1; + dftlen <<= 1; + break; - case 92160: - // 50, 60, 70, 80, 90 MHz @ 92.16 Ms/s - Ncp *= 3; - dftlen *= 3; - break; + case 92160: + // 50, 60, 70, 80, 90 MHz @ 92.16 Ms/s + Ncp *= 3; + dftlen *= 3; + break; - case 122880: - // 70, 80, 90, 100 MHz @ 122.88 Ms/s - Ncp <<= 2; - dftlen <<= 2; - break; + case 122880: + // 70, 80, 90, 100 MHz @ 122.88 Ms/s + Ncp <<= 2; + dftlen <<= 2; + break; - case 184320: - // 100 MHz @ 184.32 Ms/s - Ncp = Ncp*6; - dftlen = dftlen*6; - break; + case 184320: + // 100 MHz @ 184.32 Ms/s + Ncp = Ncp * 6; + dftlen = dftlen * 6; + break; - case 245760: - // 200 MHz @ 245.76 Ms/s - Ncp <<= 3; - dftlen <<= 3; - break; + case 245760: + // 200 MHz @ 245.76 Ms/s + Ncp <<= 3; + dftlen <<= 3; + break; - default: - AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); + default: + AssertFatal(1 == 0, "sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu); } - #ifdef NR_PRACH_DEBUG - LOG_I(PHY, "PRACH [UE %d] Ncp %d, dftlen %d \n", Mod_id, Ncp, dftlen); - #endif +#ifdef NR_PRACH_DEBUG + LOG_I(PHY, "PRACH [UE %d] Ncp %d, dftlen %d \n", ue->Mod_id, Ncp, dftlen); +#endif /******************************************************** * @@ -390,7 +316,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t * to compute quantized roots of unity ru(n) = 32767 * exp j*[ (2 * PI * n) / N_ZC ] * * In compute_prach_seq: - * to calculate Xu = DFT xu = xu (inv_u*k) * Xu[0] (This is a Zadoff-Chou sequence property: DFT ZC sequence is another ZC sequence) + * to calculate Xu = DFT xu = xu (inv_u*k) * Xu[0] (This is a Zadoff-Chou sequence property: DFT ZC sequence is another ZC + * sequence) * * In generate_prach: * to do the cyclic-shifted DFT by multiplying Xu[k] * ru[k*preamble_shift] as: @@ -398,118 +325,55 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t * *********************************************************/ - c16_t *Xu = ue->X_u[preamble_offset - first_nonzero_root_idx]; + const c16_t *Xu = ue->X_u[preamble_offset - first_nonzero_root_idx]; #if defined (PRACH_WRITE_OUTPUT_DEBUG) - LOG_M("X_u.m", "X_u", (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx], N_ZC, 1, 1); - #endif + LOG_M("X_u.m", "X_u", (int16_t *)ue->X_u[preamble_offset - first_nonzero_root_idx], N_ZC, 1, 1); +#endif - for (offset=0,offset2=0; offset= N_ZC) + offset2 -= N_ZC; + const c16_t Xu_t = c16xmulConstShift(Xu[offset], amp, 15); + const double w = 2 * M_PI * (double)offset2 / N_ZC; + const c16_t ru = {.r = (int16_t)(floor(32767.0 * cos(w))), .i = (int16_t)(floor(32767.0 * sin(w)))}; + const c16_t p = c16mulShift(Xu_t, ru, 15); + prachF[k++] = p; + if (k == dftlen) + k = 0; + } - if (offset2 >= N_ZC) - offset2 -= N_ZC; - const c16_t Xu_t = c16xmulConstShift(Xu[offset], amp, 15); - const double w = 2 * M_PI * (double)offset2 / N_ZC; - const c16_t ru = {.r = (int16_t)(floor(32767.0 * cos(w))), .i = (int16_t)(floor(32767.0 * sin(w)))}; - const c16_t p = c16mulShift(Xu_t, ru, 15); - prachF[k++] = p; - - if (k * 2 == dftlen) - k = 0; - } - - #if defined (PRACH_WRITE_OUTPUT_DEBUG) +#if defined(PRACH_WRITE_OUTPUT_DEBUG) LOG_M("prachF.m", "prachF", &prachF[1804], 1024, 1, 1); LOG_M("Xu.m", "Xu", Xu, N_ZC, 1, 1); - #endif +#endif - // This is after cyclic prefix - c16_t *prach2 = prach + Ncp; + // This is after cyclic prefix const idft_size_idx_t idft_size = get_idft(dftlen); idft(idft_size, (int16_t *)prachF, (int16_t *)prach, 1); - memmove(prach2, prach, (dftlen << 2)); + } - if (prach_sequence_length == 0) { - if (prach_fmt_id == 0) { - // here we have | empty | Prach | - memcpy(prach, prach + dftlen, (Ncp << 2)); - // here we have | Prefix | Prach | - prach_len = dftlen + Ncp; - } else if (prach_fmt_id == 1) { - // here we have | empty | Prach | empty | - memcpy(prach2 + dftlen, prach2, (dftlen << 2)); - // here we have | empty | Prach | Prach | - memcpy(prach, prach + dftlen * 2, (Ncp << 2)); - // here we have | Prefix | Prach | Prach | - prach_len = (dftlen * 2) + Ncp; - } else if (prach_fmt_id == 2 || prach_fmt_id == 3) { - // here we have | empty | Prach | empty | empty | empty | - memcpy(prach2 + dftlen, prach2, (dftlen << 2)); - // here we have | empty | Prach | Prach | empty | empty | - memcpy(prach2 + dftlen * 2, prach2, (dftlen << 3)); - // here we have | empty | Prach | Prach | Prach | Prach | - memcpy(prach, prach + dftlen * 4, (Ncp << 2)); - // here we have | Prefix | Prach | Prach | Prach | Prach | - prach_len = (dftlen * 4) + Ncp; - } - } else { // short PRACH sequence - if (prach_fmt_id == 9) { - // here we have | empty | Prach | - memcpy(prach, prach + dftlen, (Ncp << 2)); - // here we have | Prefix | Prach | - prach_len = (dftlen*1)+Ncp; - } else if (prach_fmt_id == 4 || prach_fmt_id == 7) { - // here we have | empty | Prach | empty | - memcpy(prach2 + dftlen, prach2, (dftlen << 2)); - // here we have | empty | Prach | Prach | - memcpy(prach, prach+(dftlen<<1), (Ncp<<2)); - // here we have | Prefix | Prach | Prach | - prach_len = (dftlen*2)+Ncp; - } else if (prach_fmt_id == 5 || prach_fmt_id == 10) { // 4xdftlen - // here we have | empty | Prach | empty | empty | empty | - memcpy(prach2 + dftlen, prach2, (dftlen << 2)); - // here we have | empty | Prach | Prach | empty | empty | - memcpy(prach2 + dftlen * 2, prach2, (dftlen << 3)); - // here we have | empty | Prach | Prach | Prach | Prach | - memcpy(prach, prach + dftlen, (Ncp << 2)); - // here we have | Prefix | Prach | Prach | Prach | Prach | - prach_len = (dftlen*4)+Ncp; - } else if (prach_fmt_id == 6) { // 6xdftlen - // here we have | empty | Prach | empty | empty | empty | empty | empty | - memcpy(prach2 + dftlen, prach2, (dftlen << 2)); - // here we have | empty | Prach | Prach | empty | empty | empty | empty | - memcpy(prach2 + dftlen * 2, prach2, (dftlen << 3)); - // here we have | empty | Prach | Prach | Prach | Prach | empty | empty | - memcpy(prach2 + dftlen * 4, prach2, (dftlen << 3)); - // here we have | empty | Prach | Prach | Prach | Prach | Prach | Prach | - memcpy(prach, prach + dftlen, (Ncp << 2)); - // here we have | Prefix | Prach | Prach | Prach | Prach | Prach | Prach | - prach_len = (dftlen*6)+Ncp; - } else if (prach_fmt_id == 8) { // 12xdftlen - // here we have | empty | Prach | empty | empty | empty | empty | empty | empty | empty | empty | empty | empty | empty | - memcpy(prach2 + dftlen, prach2, (dftlen << 2)); - // here we have | empty | Prach | Prach | empty | empty | empty | empty | empty | empty | empty | empty | empty | empty | - memcpy(prach2 + dftlen * 2, prach2, (dftlen << 3)); - // here we have | empty | Prach | Prach | Prach | Prach | empty | empty | empty | empty | empty | empty | empty | empty | - memcpy(prach2 + dftlen * 4, prach2, (dftlen << 3)); - // here we have | empty | Prach | Prach | Prach | Prach | Prach | Prach | empty | empty | empty | empty | empty | empty | - memcpy(prach2 + dftlen * 6, prach2, (dftlen << 2) * 6); - // here we have | empty | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | - memcpy(prach, prach + dftlen, (Ncp << 2)); - // here we have | Prefix | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | Prach | - prach_len = (dftlen*12)+Ncp; - } + c16_t *out = txData[0] + prach_start; + memcpy(out, prach + dftlen - Ncp, Ncp * sizeof(*prach)); + out += Ncp; + const int copies[11] = {1, 2, 4, 4, 2, 4, 6, 2, 12, 1, 4}; + DevAssert(prach_fmt_id < sizeofArray(copies)); + for (int i = 0; i < copies[prach_fmt_id]; i++) { + memcpy(out, prach, dftlen * sizeof(*prach)); + out += dftlen; } #ifdef NR_PRACH_DEBUG - LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d\n", Mod_id, fp->N_RB_UL, prach_start, prach_len); -#endif - - memcpy(txData[0] + prach_start, prach, sizeof(c16_t) * prach_len); - -#ifdef PRACH_WRITE_OUTPUT_DEBUG - LOG_M("prach_tx0.m", "prachtx0", prach + (Ncp << 1), prach_len - Ncp, 1, 1); - LOG_M("Prach_txsig.m", "txs", (int16_t *)(&txdata[0][prach_start]), 2 * (prach_start + prach_len), 1, 1) + LOG_I(PHY, + "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d\n", + ue->Mod_id, + fp->N_RB_UL, + prach_start, + out - (txData[0] + prach_start)); #endif return signal_energy((int *)prach, 256); 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 ed348986e8..68904f1fa2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -168,15 +168,20 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /** \brief This function does IFFT for PUSCH */ -uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, - const uint8_t slot, - const NR_DL_FRAME_PARMS *frame_parms, - const uint8_t n_antenna_ports, - c16_t **txdataF, - c16_t **txdata, - uint32_t linktype, - bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT], - bool no_phase_pre_comp); +uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot, + const NR_DL_FRAME_PARMS *frame_parms, + const uint8_t n_antenna_ports, + c16_t **txdataF, + c16_t **txdata, + uint32_t linktype, + bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT], + bool no_phase_pre_comp); + +bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + c16_t **txdataF, + nr_phy_data_tx_t *phy_data, + bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]); void clean_UE_harq(PHY_VARS_NR_UE *UE); @@ -330,7 +335,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_scope_req_t *scope_req); int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot, c16_t **txData); - +void apply_ntn_config(PHY_VARS_NR_UE *UE, + NR_DL_FRAME_PARMS *fp, + int hfn_rx, + int frame_rx, + int slot_rx, + int *duration_rx_to_tx, + int *timing_advance, + int *ntn_koffset, + bool *ntn_targetcell); +void fix_ntn_epoch_hfn(PHY_VARS_NR_UE *UE, int hfn, int frame); +void apply_ntn_timing_advance_and_doppler(PHY_VARS_NR_UE *UE, const NR_DL_FRAME_PARMS *fp, int abs_subframe_tx); void dump_nrdlsch(PHY_VARS_NR_UE *ue,uint8_t gNB_id,uint8_t nr_slot_rx,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid); void nr_a_sum_b(c16_t *input_x, c16_t *input_y, unsigned short nb_rb); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c index 8199b45fc6..436ebfe5e0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c @@ -29,10 +29,11 @@ */ #include "PHY/defs_nr_UE.h" -#include "PHY/phy_extern_nr_ue.h" #include "nr_transport_proto_ue.h" #include "executables/softmodem-common.h" +extern PHY_VARS_NR_UE ***PHY_vars_UE_g; + void nr_get_carrier_frequencies(PHY_VARS_NR_UE *ue, uint64_t *dl_carrier, uint64_t *ul_carrier){ NR_DL_FRAME_PARMS *fp = &ue->frame_parms; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 310fa7dc5f..8251f278ad 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -1502,15 +1502,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS); } -uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, - const uint8_t slot, - const NR_DL_FRAME_PARMS *frame_parms, - const uint8_t n_antenna_ports, - c16_t **txdataF, - c16_t **txdata, - uint32_t linktype, - bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT], - bool no_phase_pre_comp) +uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot, + const NR_DL_FRAME_PARMS *frame_parms, + const uint8_t n_antenna_ports, + c16_t **txdataF, + c16_t **txdata, + uint32_t linktype, + bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT], + bool no_phase_pre_comp) { int N_RB = (linktype == link_type_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_UL; diff --git a/openair1/PHY/TOOLS/calibration_test.c b/openair1/PHY/TOOLS/calibration_test.c index 4d88ab542a..8007040499 100644 --- a/openair1/PHY/TOOLS/calibration_test.c +++ b/openair1/PHY/TOOLS/calibration_test.c @@ -108,10 +108,6 @@ int main(int argc, char **argv) { .sdr_addrs=usrp_addrs, //! Auto calibration flag .autocal={0}, - //! rf devices work with x bits iqs when oai have its own iq format - //! the two following parameters are used to convert iqs - .iq_txshift=0, - .iq_rxrescale=0, //! Configuration file for LMS7002M .configFilename="", //! remote IP/MAC addr for Ethernet interface diff --git a/openair1/PHY/TOOLS/signal_energy.c b/openair1/PHY/TOOLS/signal_energy.c index a7c314dd44..4e29f0ab2b 100644 --- a/openair1/PHY/TOOLS/signal_energy.c +++ b/openair1/PHY/TOOLS/signal_energy.c @@ -180,3 +180,39 @@ int32_t interference_power(int32_t *input, uint32_t length) return temp; } +// Computes transmitter energy level +double compute_tx_energy_level(c16_t **txdata, int nb_antennas, int offset, int length, int n_trials) +{ + double txlev_sum = 0, atxlev[nb_antennas]; + for (int aa = 0; aa < nb_antennas; aa++) { + atxlev[aa] = signal_energy((int32_t *)&txdata[aa][offset], length); + + txlev_sum += atxlev[aa]; + + if (n_trials == 1) + printf("txlev[%d] = %f (%f dB) txlev_sum %f\n", aa, atxlev[aa], 10 * log10(atxlev[aa]), txlev_sum); + } + return txlev_sum; +} + +// Computes noise variance from the input transmit energy and SNR +double compute_noise_variance(double txlev_sum, + uint16_t ofdm_symbol_size, + int N_RB, + uint8_t precod_nbr_layers, + double SNR, + int n_trials) +{ + // Justification of division by precod_nbr_layers: + // When the channel is the identity matrix, the results in terms of SNR should be almost equal for 2x2 and 4x4. + double sigma_dB = 10 * log10(txlev_sum / precod_nbr_layers * ((double)ofdm_symbol_size / (12 * N_RB))) - SNR; + double sigma = pow(10, sigma_dB / 10); + + if (n_trials == 1) + printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n", + sigma, + sigma_dB, + 10 * log10(txlev_sum), + (double)(double)ofdm_symbol_size / (12 * N_RB)); + return sigma; +} diff --git a/openair1/PHY/TOOLS/tests/test_dft.c b/openair1/PHY/TOOLS/tests/test_dft.c index 8b4c344c6c..abcb0c05f7 100644 --- a/openair1/PHY/TOOLS/tests/test_dft.c +++ b/openair1/PHY/TOOLS/tests/test_dft.c @@ -70,6 +70,7 @@ void math_dft(cd_t *in, cd_t *out, int len) int main(void) { int ret = 0; + randominit(); load_dftslib(); c16_t *d16 = malloc16(12 * dftFtab[sizeofArray(dftFtab) - 1].size * sizeof(*d16)); c16_t *o16 = malloc16(12 * dftFtab[sizeofArray(dftFtab) - 1].size * sizeof(*d16)); diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index c5a8ab13b7..36fc496545 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -927,6 +927,14 @@ double signal_energy_fp(double *s_re[2], double *s_im[2], uint32_t nb_antennas, */ double signal_energy_fp2(struct complexd *s, uint32_t length); +double compute_tx_energy_level(c16_t **txdata, int nb_antennas, int offset, int length, int n_trials); + +double compute_noise_variance(double txlev_sum, + uint16_t ofdm_symbol_size, + int N_RB, + uint8_t precod_nbr_layers, + double SNR, + int n_trials); int32_t iSqrt(int32_t value); uint8_t log2_approx(uint32_t); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 6b45551b7f..851f8a2b6b 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -47,6 +47,8 @@ #define MAX_NUM_RU_PER_gNB 8 #define MAX_PUCCH0_NID 8 +#define NR_SRS_IDFT_OVERSAMP_FACTOR 2 +#define NR_SRS_DETECTION_THRESHOLD 10 typedef struct { int nb_id; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 935226b238..a166dc13cd 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -329,11 +329,6 @@ typedef struct UE_NR_SCAN_INFO_s { int32_t freq_offset_Hz[3][10]; } UE_NR_SCAN_INFO_t; -typedef struct { - bool update; - fapi_nr_dl_ntn_config_command_pdu ntn_config_params; -} ntn_config_message_t; - /// Top-level PHY Data Structure for UE typedef struct PHY_VARS_NR_UE_s { openair0_config_t openair0_cfg[MAX_CARDS]; @@ -462,12 +457,15 @@ typedef struct PHY_VARS_NR_UE_s { double initial_fo; /// initial frequency offset provided by the user int cont_fo_comp; /// flag enabling the continuous frequency offset estimation and compensation - double freq_offset; /// currently compensated frequency offset - double freq_off_acc; /// accumulated frequency error (for PI controller) + double freq_offset; /// currently compensated DL frequency offset (without dl_Doppler_shift) + double freq_off_acc; /// accumulated DL frequency error (for PI controller) + double dl_Doppler_shift; /// calculated DL Doppler shift + double ul_Doppler_shift; /// calculated UL Doppler shift /// Timing Advance updates variables /// Timing advance update computed from the TA command signalled from gNB - int timing_advance; + int timing_advance; /// corresponds to N_TA + int timing_advance_ntn; /// corresponds to N_common_TA_adj + N_UE_TA_adj int N_TA_offset; ///timing offset used in TDD int ta_frame; int ta_slot; @@ -524,7 +522,6 @@ typedef struct PHY_VARS_NR_UE_s { Actor_t sync_actor; Actor_t *dl_actors; Actor_t *ul_actors; - ntn_config_message_t* ntn_config_message; pthread_t main_thread; pthread_t stat_thread; } PHY_VARS_NR_UE; @@ -538,11 +535,14 @@ typedef struct { /// NR slot index within frame_rx [0 .. slots_per_frame - 1] to act upon for transmission int nr_slot_rx; int tx_slot_type; - //#endif /// frame to act upon for transmission int frame_tx; /// frame to act upon for reception int frame_rx; + /// hyper frame number to act upon for transmission + int hfn_tx; + /// hyper frame number to act upon for reception + int hfn_rx; } UE_nr_rxtx_proc_t; typedef struct { diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 23972fc9f2..b9948eaf92 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -165,11 +165,6 @@ void init_prach_list(prach_list_t *); typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; -typedef uint32_t (*get_samples_per_slot_t)(int slot, const NR_DL_FRAME_PARMS *fp); -typedef uint32_t (*get_slot_from_timestamp_t)(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp); - -typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, const NR_DL_FRAME_PARMS *fp, unsigned int sl_ahead); - struct NR_DL_FRAME_PARMS { /// frequency range frequency_range_t freq_range; @@ -225,12 +220,6 @@ struct NR_DL_FRAME_PARMS { uint16_t slots_per_frame; /// Number of samples in a subframe 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 @@ -336,4 +325,17 @@ typedef struct { #define KHz (1000UL) #define MHz (1000*KHz) +// Get symbol duration within slot in samples +uint32_t get_samples_symbol_duration(const NR_DL_FRAME_PARMS *fp, int slot, int start_symbol, int num_symbols); +// Get timestamp of symbol within slot in samples +uint32_t get_samples_symbol_timestamp(const NR_DL_FRAME_PARMS *fp, int slot, int symbol); +// Get slot duration between two slot +uint32_t get_samples_slot_duration(const NR_DL_FRAME_PARMS *fp, unsigned int start_slot, unsigned int num_slots); +// Get timestamp of slot from start of frame +uint32_t get_samples_slot_timestamp(const NR_DL_FRAME_PARMS *fp, unsigned int slot); +// Get slot from timestamp +uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp); +// Get number of samples in the slot +uint32_t get_samples_per_slot(int slot, const NR_DL_FRAME_PARMS *fp); + #endif diff --git a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h index a2011e1fa6..5b60f3bdf6 100644 --- a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h +++ b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h @@ -372,7 +372,8 @@ bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms, nr_srs_info_t *nr_srs_info, int16_t amp, frame_t frame_number, - slot_t slot_number); + slot_t slot_number, + uint8_t nb_antennas); void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, const csi_mapping_parms_t *phy_csi_parms, const int16_t amp, diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common_srs.c b/openair1/PHY/nr_phy_common/src/nr_phy_common_srs.c index 9d91986b50..f258b92205 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common_srs.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common_srs.c @@ -146,11 +146,12 @@ bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms, nr_srs_info_t *nr_srs_info, int16_t amp, frame_t frame_number, - slot_t slot_number) + slot_t slot_number, + uint8_t nb_antennas) { uint8_t K_TC = 2 << nr_srs_info->comb_size; /* Number of antenna ports (M) can't be higher than number of physical antennas (N): M <= N */ - int N_ap = nr_srs_info->n_srs_ports > frame_parms->nb_antennas_tx ? frame_parms->nb_antennas_tx : nr_srs_info->n_srs_ports; + int N_ap = nr_srs_info->n_srs_ports > nb_antennas ? nb_antennas : nr_srs_info->n_srs_ports; uint8_t l0 = frame_parms->symbols_per_slot - 1 - nr_srs_info->l_offset; // Starting symbol position in the time domain uint8_t n_SRS_cs_max = srs_max_number_cs[nr_srs_info->comb_size]; int m_SRS_b = get_m_srs(nr_srs_info->C_SRS, nr_srs_info->B_SRS); // Number of resource blocks @@ -180,6 +181,11 @@ bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms, LOG_I(NR_PHY,"M_sc_b_SRS = %i\n", M_sc_b_SRS); #endif + AssertFatal(l0 + nr_srs_info->N_symb_SRS - 1 < frame_parms->symbols_per_slot, + "last symbol index %d should be < %d\n", + l0 + nr_srs_info->N_symb_SRS, + frame_parms->symbols_per_slot - 1); + // Validation of SRS config parameters if (nr_srs_info->R == 0) { diff --git a/openair1/PHY/phy_extern_nr_ue.h b/openair1/PHY/phy_extern_nr_ue.h deleted file mode 100644 index 2c4679dddd..0000000000 --- a/openair1/PHY/phy_extern_nr_ue.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef __PHY_EXTERN_NR_UE__H__ -#define __PHY_EXTERN_NR_UE__H__ - -#include "PHY/defs_nr_UE.h" -extern PHY_VARS_NR_UE ***PHY_vars_UE_g; - -extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; -extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; -extern uint64_t sidelink_frequency[MAX_NUM_CCs][4]; - -#endif /*__PHY_EXTERN_H__ */ - diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c index 9479e960a8..4c2c19847c 100644 --- a/openair1/SCHED_NR/phy_frame_config_nr.c +++ b/openair1/SCHED_NR/phy_frame_config_nr.c @@ -199,8 +199,8 @@ void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu) switch (mu) { case 0: - pc->num_dl_slots = 3; - pc->num_ul_slots = 1; + pc->num_dl_slots = 7; + pc->num_ul_slots = 2; break; case 1: @@ -209,8 +209,8 @@ void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu) break; case 3: - pc->num_dl_slots = 27; - pc->num_ul_slots = 12; + pc->num_dl_slots = 7; + pc->num_ul_slots = 2; break; default: @@ -226,7 +226,7 @@ void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu) pc->tdd_slot_bitmap[i].num_dl_symbols = 6; pc->tdd_slot_bitmap[i].num_ul_symbols = 4; } - for (int i = pc->num_ul_slots; i < fs.numb_slots_period; i++) { + for (int i = fs.numb_slots_period - pc->num_ul_slots; i < fs.numb_slots_period; i++) { pc->tdd_slot_bitmap[i].slot_type = TDD_NR_UPLINK_SLOT; pc->tdd_slot_bitmap[i].num_dl_symbols = 0; pc->tdd_slot_bitmap[i].num_ul_symbols = 0; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6ea1a197e2..ff82310d29 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -66,7 +66,6 @@ static void nr_fill_indication(PHY_VARS_gNB *gNB, int beam_index_allocation(bool das, int fapi_beam_index, - const nfapi_nr_analog_beamforming_ve_t *analog_bf, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, @@ -77,7 +76,8 @@ int beam_index_allocation(bool das, if (das) return fapi_beam_index; - int ru_beam_idx = analog_bf->analog_beam_list[fapi_beam_index].value; + AssertFatal(IS_BIT_SET(fapi_beam_index, 15), "Can't handle preconfigured DBM yet\n"); + int ru_beam_idx = fapi_beam_index & 0x7fff; int idx = -1; for (int j = 0; j < common_vars->num_beams_period; j++) { // L2 analog beam implementation is slot based, so we need to verify occupancy for the whole slot @@ -160,7 +160,6 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n int bitmap = SL_to_bitmap(ssb_start_symbol, 4); // 4 ssb symbols int beam_nb = beam_index_allocation(gNB->enable_analog_das, pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, - &cfg->analog_beamforming_ve, &gNB->common_vars, slot, fp->symbols_per_slot, @@ -229,7 +228,6 @@ static void nr_generate_csi_rs_gNB(PHY_VARS_gNB *gNB, csi_bitmap |= ((1 << lprime_num) - 1) << mapping_parms.loverline[j]; int beam_nb = beam_index_allocation(gNB->enable_analog_das, pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, - &cfg->analog_beamforming_ve, &gNB->common_vars, slot, gNB->frame_parms.symbols_per_slot, @@ -719,9 +717,10 @@ static void fill_ul_rb_mask(PHY_VARS_gNB *gNB, if (!(srs && srs->active && srs->frame == frame_rx && srs->slot == slot_rx)) continue; nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; + const uint8_t l0 = gNB->frame_parms.symbols_per_slot - 1 - srs_pdu->time_start_position; for (int symbol = 0; symbol < (1 << srs_pdu->num_symbols); symbol++) { for (int rb = srs_pdu->bwp_start; rb < (srs_pdu->bwp_start + srs_pdu->bwp_size); rb++) { - rb_mask_ul[srs_pdu->time_start_position + symbol][rb >> 5] |= 1U << (rb & 31); + rb_mask_ul[l0 + symbol][rb >> 5] |= 1U << (rb & 31); } } } @@ -859,6 +858,139 @@ static bool check_and_configure_srs_info(nfapi_nr_srs_pdu_t *srs_config_pdu, nr_ return false; } +void nr_srs_rx_procedures(PHY_VARS_gNB *gNB, + int frame_rx, + int slot_rx, + uint8_t nb_antennas_rx, + uint8_t N_ap, + uint8_t N_symb_SRS, + uint16_t ofdm_symbol_size, + NR_gNB_SRS_t *srs, + nr_srs_info_t *nr_srs_info, + int *srs_est, + c16_t srs_estimated_channel_freq[][N_ap][ofdm_symbol_size * N_symb_SRS], + c16_t srs_estimated_channel_time[][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], + int16_t *snr_per_rb, + uint16_t *timing_advance_offset, + int16_t *timing_advance_offset_nsec) +{ + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; + nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; + c16_t srs_received_signal[nb_antennas_rx][ofdm_symbol_size * N_symb_SRS]; + c16_t srs_received_noise[nb_antennas_rx][ofdm_symbol_size * N_symb_SRS]; + c16_t srs_estimated_channel_time_shifted[nb_antennas_rx][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size]; + + start_meas(&gNB->generate_srs_stats); + + if (check_and_configure_srs_info(srs_pdu, nr_srs_info)) { + generate_srs_nr(frame_parms, + nr_srs_info->srs_generated_signal, + 0, + srs_pdu->bwp_start, + nr_srs_info, + AMP, + frame_rx, + slot_rx, + nb_antennas_rx); + } + + stop_meas(&gNB->generate_srs_stats); + c16_t **rxdataF = gNB->common_vars.rxdataF[srs->beam_nb]; + start_meas(&gNB->get_srs_signal_stats); + *srs_est = nr_get_srs_signal(gNB, rxdataF, frame_rx, slot_rx, srs_pdu, nr_srs_info, srs_received_signal, srs_received_noise); + stop_meas(&gNB->get_srs_signal_stats); + + uint32_t signal_power_avg = 0; + uint32_t noise_power_avg = 0; + int16_t noise_power_per_rb[srs_pdu->bwp_size]; + memset(noise_power_per_rb, 0, srs_pdu->bwp_size * sizeof(int16_t)); + + if (*srs_est >= 0) { + start_meas(&gNB->srs_channel_estimation_stats); + for (int ant_rx_ind = 0; ant_rx_ind < nb_antennas_rx; ant_rx_ind++) { + uint32_t noise_power = 0; + for (int p_ind = 0; p_ind < N_ap; p_ind++) { + uint32_t signal_power = 0; + nr_srs_channel_estimation(ant_rx_ind, + p_ind, + ofdm_symbol_size, + frame_parms->first_carrier_offset, + N_symb_SRS, + srs_pdu, + nr_srs_info, + nr_srs_info->srs_generated_signal[p_ind], + srs_received_signal[ant_rx_ind], + srs_received_noise[ant_rx_ind], + srs_estimated_channel_freq[ant_rx_ind][p_ind], + srs_estimated_channel_time[ant_rx_ind][p_ind], + srs_estimated_channel_time_shifted[ant_rx_ind][p_ind], + &signal_power, + &noise_power, + noise_power_per_rb); + + signal_power_avg += signal_power; + + T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, + T_INT(gNB->Mod_id), + T_INT(srs_pdu->rnti), + T_INT(frame_rx), + T_INT(slot_rx), + T_INT(ant_rx_ind), + T_INT(p_ind), + T_BUFFER(srs_estimated_channel_freq[ant_rx_ind][p_ind], N_symb_SRS * ofdm_symbol_size * sizeof(c16_t))); + + T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE, + T_INT(gNB->Mod_id), + T_INT(srs_pdu->rnti), + T_INT(frame_rx), + T_INT(slot_rx), + T_INT(ant_rx_ind), + T_INT(p_ind), + T_BUFFER(srs_estimated_channel_time_shifted[ant_rx_ind][p_ind], + NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size * sizeof(c16_t))); + } + noise_power_avg += noise_power; + } + signal_power_avg /= (nb_antennas_rx * N_ap); + noise_power_avg /= nb_antennas_rx; + signal_power_avg = max(signal_power_avg, 1); + gNB->srs->snr = dB_fixed(signal_power_avg) - dB_fixed(max(noise_power_avg, 1)); + + const uint16_t m_SRS_b = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index); + for (int rb = 0; rb < m_SRS_b; rb++) { + snr_per_rb[rb] = dB_fixed(signal_power_avg) - dB_fixed(max(noise_power_per_rb[rb] / nb_antennas_rx, 1)); + } + stop_meas(&gNB->srs_channel_estimation_stats); + + start_meas(&gNB->srs_timing_advance_stats); + for (int ant_rx_ind = 0; ant_rx_ind < nb_antennas_rx; ant_rx_ind++) { + nr_est_srs_timing_advance_offset(ofdm_symbol_size, + srs_estimated_channel_time[ant_rx_ind], + ant_rx_ind, + N_ap, + frame_parms->samples_per_frame, + timing_advance_offset, + &timing_advance_offset_nsec[ant_rx_ind]); + } + stop_meas(&gNB->srs_timing_advance_stats); + + T(T_GNB_PHY_UL_SNR_ESTIMATE, + T_INT(0), + T_INT(srs_pdu->rnti), + T_INT(frame_rx), + T_INT(0), + T_INT(0), + T_BUFFER(snr_per_rb, srs_pdu->bwp_size * sizeof(int16_t))); + + T(T_GNB_PHY_UL_SRS_TOA_NS, + T_INT(gNB->Mod_id), + T_INT(srs_pdu->rnti), + T_INT(frame_rx), + T_INT(slot_rx), + T_BUFFER(timing_advance_offset_nsec, nb_antennas_rx * sizeof(int16_t))); + } +} + int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, NR_UL_IND_t *UL_INFO) { /* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */ @@ -867,9 +999,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N int pusch_DTX = 0; const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - const int symb_sz = frame_parms->ofdm_symbol_size; + const uint16_t ofdm_symbol_size = frame_parms->ofdm_symbol_size; const int nb_symb = frame_parms->symbols_per_slot; - const int ant = gNB->frame_parms.nb_antennas_rx; + const uint8_t nb_antennas_rx = frame_parms->nb_antennas_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); { @@ -894,7 +1026,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N gNB_I0_measurements(gNB, slot_rx, first_symb, num_symb, rb_mask_ul); } - const int soffset = (slot_rx & 3) * nb_symb * symb_sz; + const int soffset = (slot_rx & 3) * nb_symb * ofdm_symbol_size; start_meas(&gNB->phy_proc_rx); for (int i = 0; i < gNB->max_nb_pucch; i++) { @@ -913,7 +1045,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N uci->pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; uci->pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t); nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &uci->pucch_pdu_format_0_1; - int offset = pucch_pdu->start_symbol_index * symb_sz + (frame_parms->first_carrier_offset + pucch_pdu->prb_start * 12); + int offset = + pucch_pdu->start_symbol_index * ofdm_symbol_size + (frame_parms->first_carrier_offset + pucch_pdu->prb_start * 12); LOG_D(NR_PHY, "frame %d, slot %d: PUCCH signal energy %d\n", frame_rx, @@ -969,17 +1102,14 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N buf[7] = (int16_t)ulsch->harq_pid; memcpy(&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset + 4], &ru->common.rxdata[0][slot_offset], - frame_parms->get_samples_per_slot(slot_rx, frame_parms) * sizeof(int32_t)); - gNB->common_vars.debugBuff_sample_offset += (frame_parms->get_samples_per_slot(slot_rx, frame_parms) + 1000 + 4); - if (gNB->common_vars.debugBuff_sample_offset > ((frame_parms->get_samples_per_slot(slot_rx, frame_parms) + 1000 + 2) * 20)) { + get_samples_per_slot(slot_rx, frame_parms) * sizeof(int32_t)); + gNB->common_vars.debugBuff_sample_offset += (get_samples_per_slot(slot_rx, frame_parms) + 1000 + 4); + if (gNB->common_vars.debugBuff_sample_offset > ((get_samples_per_slot(slot_rx, frame_parms) + 1000 + 2) * 20)) { FILE *f; f = fopen("rxdata_buff.raw", "w"); if (f == NULL) exit(1); - fwrite((int16_t *)gNB->common_vars.debugBuff, - 2, - (frame_parms->get_samples_per_slot(slot_rx, frame_parms) + 1000 + 4) * 20 * 2, - f); + fwrite((int16_t *)gNB->common_vars.debugBuff, 2, (get_samples_per_slot(slot_rx, frame_parms) + 1000 + 4) * 20 * 2, f); fclose(f); exit(-1); } @@ -993,7 +1123,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ULSCH_id]; pusch_vars->ulsch_power_tot = 0; pusch_vars->ulsch_noise_power_tot = 0; - for (int aarx = 0; aarx < ant; aarx++) { + for (int aarx = 0; aarx < nb_antennas_rx; aarx++) { pusch_vars->ulsch_power[aarx] /= num_dmrs; pusch_vars->ulsch_power_tot += pusch_vars->ulsch_power[aarx]; pusch_vars->ulsch_noise_power[aarx] /= num_dmrs; @@ -1068,80 +1198,38 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N start_meas(&gNB->rx_srs_stats); + uint8_t N_symb_SRS = 1 << srs->srs_pdu.num_symbols; + uint8_t N_ap = 1 << srs->srs_pdu.num_ant_ports; + int16_t snr_per_rb[srs->srs_pdu.bwp_size]; nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; - uint8_t N_symb_SRS = 1 << srs_pdu->num_symbols; - c16_t srs_received_signal[ant][symb_sz * N_symb_SRS]; - c16_t srs_received_noise[ant][symb_sz * N_symb_SRS]; - c16_t srs_estimated_channel_freq[ant][1 << srs_pdu->num_ant_ports][symb_sz * N_symb_SRS] __attribute__((aligned(32))); - c16_t srs_estimated_channel_time[ant][1 << srs_pdu->num_ant_ports][symb_sz] __attribute__((aligned(32))); - c16_t srs_estimated_channel_time_shifted[ant][1 << srs_pdu->num_ant_ports][symb_sz]; - int16_t snr_per_rb[srs_pdu->bwp_size]; + uint16_t timing_advance_offset; + int16_t timing_advance_offset_nsec[nb_antennas_rx]; + int srs_est; - start_meas(&gNB->generate_srs_stats); + c16_t srs_estimated_channel_freq[nb_antennas_rx][N_ap][ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32))); + c16_t srs_estimated_channel_time[nb_antennas_rx][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size] + __attribute__((aligned(32))); - if (check_and_configure_srs_info(srs_pdu, gNB->nr_srs_info[i])) { - generate_srs_nr(frame_parms, - gNB->nr_srs_info[i]->srs_generated_signal, - 0, - srs_pdu->bwp_start, - gNB->nr_srs_info[i], - AMP, - frame_rx, - slot_rx); - } - stop_meas(&gNB->generate_srs_stats); - c16_t **rxdataF = gNB->common_vars.rxdataF[srs->beam_nb]; - start_meas(&gNB->get_srs_signal_stats); - int srs_est = - nr_get_srs_signal(gNB, rxdataF, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal, srs_received_noise); - stop_meas(&gNB->get_srs_signal_stats); - - if (srs_est >= 0) { - start_meas(&gNB->srs_channel_estimation_stats); - nr_srs_channel_estimation(gNB, - frame_rx, - slot_rx, - srs_pdu, - gNB->nr_srs_info[i], - (const c16_t **)gNB->nr_srs_info[i]->srs_generated_signal, - srs_received_signal, - srs_received_noise, - srs_estimated_channel_freq, - srs_estimated_channel_time, - srs_estimated_channel_time_shifted, - snr_per_rb, - &gNB->srs->snr); - stop_meas(&gNB->srs_channel_estimation_stats); - } + nr_srs_rx_procedures(gNB, + frame_rx, + slot_rx, + nb_antennas_rx, + N_ap, + N_symb_SRS, + ofdm_symbol_size, + srs, + gNB->nr_srs_info[i], + &srs_est, + srs_estimated_channel_freq, + srs_estimated_channel_time, + snr_per_rb, + &timing_advance_offset, + timing_advance_offset_nsec); if ((gNB->srs->snr * 10) < gNB->srs_thres) { srs_est = -1; } - T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, - T_INT(0), - T_INT(srs_pdu->rnti), - T_INT(frame_rx), - T_INT(0), - T_INT(0), - T_BUFFER(srs_estimated_channel_freq[0][0], symb_sz * sizeof(int32_t))); - - T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE, - T_INT(0), - T_INT(srs_pdu->rnti), - T_INT(frame_rx), - T_INT(0), - T_INT(0), - T_BUFFER(srs_estimated_channel_time_shifted[0][0], symb_sz * sizeof(int32_t))); - - T(T_GNB_PHY_UL_SNR_ESTIMATE, - T_INT(0), - T_INT(srs_pdu->rnti), - T_INT(frame_rx), - T_INT(0), - T_INT(0), - T_BUFFER(snr_per_rb, srs_pdu->bwp_size * sizeof(int16_t))); - UL_INFO->srs_ind.sfn = frame_rx; UL_INFO->srs_ind.slot = slot_rx; @@ -1150,13 +1238,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N nfapi_nr_srs_indication_pdu_t *srs_indication = UL_INFO->srs_pdu_list + UL_INFO->srs_ind.number_of_pdus++; srs_indication->handle = srs_pdu->handle; srs_indication->rnti = srs_pdu->rnti; - start_meas(&gNB->srs_timing_advance_stats); - srs_indication->timing_advance_offset = - srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, srs_estimated_channel_time[0]) : 0xFFFF; - stop_meas(&gNB->srs_timing_advance_stats); - srs_indication->timing_advance_offset_nsec = - srs_est >= 0 ? (int16_t)((((int32_t)srs_indication->timing_advance_offset - 31) * ((int32_t)TC_NSEC_x32768)) >> 15) - : 0xFFFF; + srs_indication->timing_advance_offset = srs_est >= 0 ? timing_advance_offset : 0xFFFF; + // TODO: currently we fill timing_advance_offset_nsec for antenna 0. Need to extend it for other antennas + srs_indication->timing_advance_offset_nsec = srs_est >= 0 ? timing_advance_offset_nsec[0] : 0x8000; switch (srs_pdu->srs_parameters_v4.usage) { case 0: LOG_W(NR_PHY, "SRS report was not requested by MAC\n"); @@ -1198,10 +1282,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N start_meas(&gNB->srs_beam_report_stats); nfapi_nr_srs_beamforming_report_t nr_srs_bf_report; nr_srs_bf_report.prg_size = srs_pdu->beamforming.prg_size; - nr_srs_bf_report.num_symbols = 1 << srs_pdu->num_symbols; + nr_srs_bf_report.num_symbols = N_symb_SRS; nr_srs_bf_report.wide_band_snr = srs_est >= 0 ? (gNB->srs->snr + 64) << 1 : 0xFF; // 0xFF will be set if this field is invalid - nr_srs_bf_report.num_reported_symbols = 1 << srs_pdu->num_symbols; + nr_srs_bf_report.num_reported_symbols = N_symb_SRS; AssertFatal(nr_srs_bf_report.num_reported_symbols == 1, "nr_srs_bf_report.num_reported_symbols %i not handled yet!\n", nr_srs_bf_report.num_reported_symbols); @@ -1239,7 +1323,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N srs_pdu, gNB->nr_srs_info[i], srs_pdu->srs_parameters_v4.iq_representation, - ant, + nb_antennas_rx, srs_pdu->srs_parameters_v4.num_total_ue_antennas, srs_pdu->srs_parameters_v4.prg_size, srs_pdu->srs_parameters_v4.srs_bandwidth_size / srs_pdu->srs_parameters_v4.prg_size, @@ -1311,7 +1395,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), - T_BUFFER(&gNB->common_vars.rxdataF[0][0][0], nb_symb * symb_sz * 4)); + T_BUFFER(&gNB->common_vars.rxdataF[0][0][0], nb_symb * ofdm_symbol_size * 4)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0); diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index da71809589..84691e9584 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -56,7 +56,6 @@ void nr_phy_free_RU(RU_t *ru); void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot); int beam_index_allocation(bool das, int fapi_beam_index, - const nfapi_nr_analog_beamforming_ve_t *analog_bf, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index a3e86ce433..4a07f7f5ca 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -39,7 +39,8 @@ #include "PHY/impl_defs_nr.h" #include "utils.h" #include "SCHED_NR_UE/phy_sch_processing_time.h" -#include "openair1/PHY/phy_extern_nr_ue.h" + +extern PHY_VARS_NR_UE ***PHY_vars_UE_g; const char *const dl_pdu_type[] = {"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH", "CSI_RS", "CSI_IM", "TA"}; const char *const ul_pdu_type[] = {"PRACH", "PUCCH", "PUSCH", "SRS"}; @@ -89,21 +90,6 @@ static void configure_dlsch(NR_UE_DLSCH_t *dlsch0, } } -static void configure_ntn_params(PHY_VARS_NR_UE *ue, fapi_nr_dl_ntn_config_command_pdu* ntn_params_message) -{ - if (!ue->ntn_config_message) { - ue->ntn_config_message = CALLOC(1, sizeof(*ue->ntn_config_message)); - } - - ue->ntn_config_message->ntn_config_params.epoch_sfn = ntn_params_message->epoch_sfn; - ue->ntn_config_message->ntn_config_params.epoch_subframe = ntn_params_message->epoch_subframe; - ue->ntn_config_message->ntn_config_params.cell_specific_k_offset = ntn_params_message->cell_specific_k_offset; - ue->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms = ntn_params_message->ntn_total_time_advance_ms; - ue->ntn_config_message->ntn_config_params.ntn_total_time_advance_drift = ntn_params_message->ntn_total_time_advance_drift; - ue->ntn_config_message->ntn_config_params.ntn_total_time_advance_drift_variant = ntn_params_message->ntn_total_time_advance_drift_variant; - ue->ntn_config_message->update = true; -} - static void configure_ta_command(PHY_VARS_NR_UE *ue, fapi_nr_ta_command_pdu *ta_command_pdu) { /* Time Alignment procedure @@ -220,9 +206,6 @@ static void nr_ue_scheduled_response_dl(NR_UE_MAC_INST_t *mac, case FAPI_NR_CONFIG_TA_COMMAND: configure_ta_command(phy, &pdu->ta_command_pdu); break; - case FAPI_NR_DL_NTN_CONFIG_PARAMS: - configure_ntn_params(phy, &pdu->ntn_config_command_pdu); - break; default: LOG_W(PHY, "unhandled dl pdu type %d \n", pdu->pdu_type); } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 43fef06ef7..c2aa0b4bd7 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -37,7 +37,6 @@ #include "defs.h" #include "PHY/defs_nr_UE.h" #include "PHY/NR_REFSIG/dmrs_nr.h" -#include "PHY/phy_extern_nr_ue.h" #include "PHY/MODULATION/modulation_UE.h" #include "PHY/INIT/nr_phy_init.h" #include "PHY/nr_phy_common/inc/nr_phy_common.h" @@ -95,6 +94,7 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, dl_ind->gNB_index = proc->gNB_id; dl_ind->module_id = ue->Mod_id; dl_ind->cc_id = ue->CC_id; + dl_ind->hfn = proc->hfn_rx; dl_ind->frame = proc->frame_rx; dl_ind->slot = proc->nr_slot_rx; dl_ind->phy_data = phy_data; @@ -304,7 +304,7 @@ static void configure_srs_info(fapi_nr_ul_config_srs_pdu *srs_config_pdu, nr_srs * send srs according to current configuration * *********************************************************************/ -static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, +bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txdataF, nr_phy_data_tx_t *phy_data, @@ -314,12 +314,13 @@ static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, return false; } + NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms); fapi_nr_ul_config_srs_pdu *srs_config_pdu = &phy_data->srs_vars.srs_config_pdu; - int first_srs_symbol = ue->frame_parms.symbols_per_slot - 1 - srs_config_pdu->time_start_position; + const uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_config_pdu->time_start_position; // Num consecutive SRS symbols according to 38.211 6.4.1.4.1 int num_srs_symbols[] = {1, 2, 4, 8, 12}; - int last_srs_symbol = first_srs_symbol + num_srs_symbols[srs_config_pdu->num_symbols] - 1; - for (int i = first_srs_symbol; i <= last_srs_symbol; i++) { + int last_srs_symbol = l0 + num_srs_symbols[srs_config_pdu->num_symbols] - 1; + for (int i = l0; i <= last_srs_symbol; i++) { was_symbol_used[i] = true; } @@ -351,8 +352,7 @@ static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, #endif configure_srs_info(srs_config_pdu, ue->nr_srs_info); - NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms); - uint16_t symbol_offset = (frame_parms->symbols_per_slot - 1 - srs_config_pdu->time_start_position)*frame_parms->ofdm_symbol_size; + uint16_t symbol_offset = l0 * frame_parms->ofdm_symbol_size; bool generated = generate_srs_nr(frame_parms, txdataF, symbol_offset, @@ -360,7 +360,8 @@ static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, ue->nr_srs_info, AMP, proc->frame_tx, - proc->nr_slot_tx); + proc->nr_slot_tx, + frame_parms->nb_antennas_tx); return generated; } @@ -400,15 +401,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n const NR_UE_PRACH *prach_var = ue->prach_vars[proc->gNB_id]; if (!prach_var->active) { start_meas_nr_ue_phy(ue, OFDM_MOD_STATS); - nr_ue_pusch_common_procedures(ue, - proc->nr_slot_tx, - &ue->frame_parms, - ue->frame_parms.nb_antennas_tx, - (c16_t **)txdataF, - txp, - link_type_ul, - was_symbol_used, - ue->no_phase_pre_comp); + nr_tx_rotation_and_ofdm_mod(proc->nr_slot_tx, + &ue->frame_parms, + ue->frame_parms.nb_antennas_tx, + (c16_t **)txdataF, + txp, + link_type_ul, + was_symbol_used, + ue->no_phase_pre_comp); stop_meas_nr_ue_phy(ue, OFDM_MOD_STATS); } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c index e03c0a1fae..40f3a8256b 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c @@ -44,8 +44,10 @@ void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind, sl_ind->gNB_index = proc->gNB_id; sl_ind->module_id = ue->Mod_id; sl_ind->cc_id = ue->CC_id; + sl_ind->hfn_rx = proc->hfn_rx; sl_ind->frame_rx = proc->frame_rx; sl_ind->slot_rx = proc->nr_slot_rx; + sl_ind->hfn_tx = proc->hfn_tx; sl_ind->frame_tx = proc->frame_tx; sl_ind->slot_tx = proc->nr_slot_tx; sl_ind->phy_data = phy_data; @@ -313,15 +315,14 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc was_symbol_used[i] = true; if (tx_action) { LOG_D(NR_PHY, "Sending Uplink data \n"); - nr_ue_pusch_common_procedures(ue, - proc->nr_slot_tx, - fp, - fp->nb_antennas_tx, - txdataF, - txp, - link_type_sl, - was_symbol_used, - ue->no_phase_pre_comp); + nr_tx_rotation_and_ofdm_mod(proc->nr_slot_tx, + fp, + fp->nb_antennas_tx, + txdataF, + txp, + link_type_sl, + was_symbol_used, + ue->no_phase_pre_comp); } LOG_D(NR_PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); diff --git a/openair1/SCHED_NR_UE/phy_sch_processing_time.h b/openair1/SCHED_NR_UE/phy_sch_processing_time.h index 896c93b9ee..1861fea9a4 100644 --- a/openair1/SCHED_NR_UE/phy_sch_processing_time.h +++ b/openair1/SCHED_NR_UE/phy_sch_processing_time.h @@ -31,6 +31,9 @@ \warning */ +#ifndef __PHY_SCH_PROCESSING_TIME_H__ +#define __PHY_SCH_PROCESSING_TIME_H__ + /* TS 38.214 Table 5.3-1: PDSCH processing time for PDSCH processing capability 1 // corresponding to the PDSCH decoding time N_1 [symbols] // where mu corresponds to the one of {mu_PDCCH, mu_PDSCH, mu_UL} @@ -139,3 +142,5 @@ static const float pusch_d_2_2_timing_capability_2[4][2] = { { 2, 9 }, { 3, 18 }, }; + +#endif diff --git a/openair1/SIMULATION/LTE_PHY/framegen.c b/openair1/SIMULATION/LTE_PHY/framegen.c index fe1c4b49b7..30fc6d5745 100644 --- a/openair1/SIMULATION/LTE_PHY/framegen.c +++ b/openair1/SIMULATION/LTE_PHY/framegen.c @@ -378,7 +378,7 @@ void lte_param_init( unsigned char transmission_mode, mac_xface->get_dci_sdu = get_dci; mac_xface->get_dlsch_sdu = get_DLSCH_pdu; - randominit(0); + randominit(); set_taus_seed(0); lte_frame_parms = &(PHY_vars_eNB_g[0]->lte_frame_parms); diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index ccdac230f8..456bc53a2c 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -249,7 +249,7 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi PHY_vars_UE[1] = malloc(sizeof(PHY_VARS_UE)); //PHY_config = malloc(sizeof(PHY_CONFIG)); mac_xface = malloc(sizeof(MAC_xface)); - randominit(0); + randominit(); set_taus_seed(0); lte_frame_parms = &(PHY_vars_eNB->lte_frame_parms); lte_frame_parms->N_RB_DL = N_RB_DL; //50 for 10MHz and 25 for 5 MHz diff --git a/openair1/SIMULATION/LTE_PHY/test.c b/openair1/SIMULATION/LTE_PHY/test.c index 6b78dad4e7..b292279860 100644 --- a/openair1/SIMULATION/LTE_PHY/test.c +++ b/openair1/SIMULATION/LTE_PHY/test.c @@ -174,7 +174,7 @@ int main(int argc, char **argv) for (i = 0; i<4; i++) ch[i] = (struct complexd*) malloc(channel_length * sizeof(struct complexd)); - randominit(0); + randominit(); set_taus_seed(0); #ifdef RF diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 76cc2e0716..7a442a4082 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -839,8 +839,7 @@ int main(int argc, char **argv) { ack_errors=0; cqi_crc_falsepositives=0; cqi_crc_falsenegatives=0; - round=0; - //randominit(0); + round = 0; harq_pid = subframe2harq_pid(&UE->frame_parms,proc_rxtx_ue->frame_tx,subframe); input_buffer_length = UE->ulsch[0]->harq_processes[harq_pid]->TBS/8; diff --git a/openair1/SIMULATION/LTE_PHY/ulsim2.c b/openair1/SIMULATION/LTE_PHY/ulsim2.c index e994d4fc36..32c0d4d8e9 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim2.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim2.c @@ -232,7 +232,7 @@ int main(int argc, char **argv) //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); // multipath channel - randominit(0); + randominit(); for (i=0; inb_antennas_tx; aa++) { diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index ea4a068b6e..d760e2394b 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -141,7 +141,7 @@ int main(int argc, char **argv) } // logInit(); - randominit(0); + randominit(); int c; while ((c = getopt(argc, argv, "--:O:df:hpVg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:L:X:")) != -1) { diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 82984657d3..40ad816d2c 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -118,6 +118,15 @@ void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t { } +/* this is a hack, but necessary for E2 agent. We compile in all of RRC + * (because of CMakeLists.txt), but we don't need it (only nr_radio_config.c). + * however, if E2 agent is defined, the following functions are used in + * rrc_gNB.c, but defined in RAN functions. In order to avoid pulling this in + * here as well, only provide a prototype (and abort if they are ever called). */ +void signal_rrc_msg(void /*const nr_rrc_class_e nr_channel, const uint32_t rrc_msg_id, const byte_array_t rrc_ba*/ ) { abort(); } +void signal_rrc_state_changed_to(void /* const gNB_RRC_UE_t *rrc_ue_context, const rrc_state_e2sm_rc_e rrc_state */) { abort(); } +void signal_ue_id(void /* const gNB_RRC_UE_t *rrc_ue_context, const uint16_t class, const uint32_t msg_id */) { abort(); } + /* Function to set or overwrite PTRS DL RRC parameters */ static void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, long *ptrsNrb, long *ptrsMcs, long *epre_Ratio, long *reOffset) { @@ -315,7 +324,7 @@ int main(int argc, char **argv) setbuf(stdout, NULL); int c; int i,aa;//,l; - double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0; + double SNR, snr0 = -2.0, snr1 = 2.0; uint8_t snr1set=0; double effRate; //float psnr; @@ -393,7 +402,7 @@ int main(int argc, char **argv) exit_fun("[NR_DLSIM] Error, configuration module init failed\n"); } - randominit(0); + randominit(); int print_perf = 0; @@ -878,8 +887,8 @@ int main(int argc, char **argv) frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; - int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); - int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0); + int slot_offset = get_samples_slot_timestamp(frame_parms, slot); + int slot_length = slot_offset - get_samples_slot_timestamp(frame_parms, slot - 1); s_re = malloc(n_tx*sizeof(double*)); s_im = malloc(n_tx*sizeof(double*)); @@ -955,8 +964,8 @@ int main(int argc, char **argv) //Configure UE NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc); - nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false, false); - nr_rrc_mac_config_req_cg(0, 0, UE_CellGroup, UE_Capability_nr); + nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false); + nr_rrc_mac_config_req_cg(0, 0, 0, 0, UE_CellGroup, UE_Capability_nr); asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup); @@ -1163,15 +1172,12 @@ int main(int argc, char **argv) } } - int txlev[n_tx]; - int txlev_sum = 0; + // Compute transmitter energy level int l_ofdm = 6; - for (aa=0; aaofdm_symbol_size + (l_ofdm-1)*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], - frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); - txlev_sum += txlev[aa]; - if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,txlev[aa],10*log10((double)txlev[aa]),txlev_sum); - } + int symbol_offset = slot_offset + l_ofdm * frame_parms->ofdm_symbol_size + (l_ofdm - 1) * frame_parms->nb_prefix_samples + + frame_parms->nb_prefix_samples0; + int symbol_length = frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples; + double txlev_sum = compute_tx_energy_level(txdata, n_tx, symbol_offset, symbol_length, n_trials); for (i = 0; i < slot_length; i++) { for (aa=0; aanb_antennas_tx; aa++) { @@ -1180,11 +1186,11 @@ int main(int argc, char **argv) } } - double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size); - //Compute AWGN variance - sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*pdsch_pdu_rel15->rbSize))) - SNR; - sigma2 = pow(10, sigma2_dB/10); - if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*pdsch_pdu_rel15->rbSize)); + double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size); + + // Estimate noise power from the transmitter level and SNR + double sigma2 = + compute_noise_variance(txlev_sum, UE->frame_parms.ofdm_symbol_size, pdsch_pdu_rel15->rbSize, 1, SNR, n_trials); for (aa = 0; aa < n_rx; aa++) { bzero(r_re[aa], slot_length * sizeof(double)); diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_common.c b/openair1/SIMULATION/NR_PHY/nr_unitary_common.c index 604e7a8c2a..ba9712391c 100644 --- a/openair1/SIMULATION/NR_PHY/nr_unitary_common.c +++ b/openair1/SIMULATION/NR_PHY/nr_unitary_common.c @@ -163,6 +163,7 @@ typedef uint32_t channel_t; int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, + const int hfn, const frame_t frame, const int slot, const rnti_t rnti, diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index c86744afaa..91d6a09569 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -176,8 +176,6 @@ int main(int argc, char **argv) float target_error_rate = 0.01; - int seed = 0; - cpuf = get_cpu_freq_GHz(); if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) { @@ -185,8 +183,7 @@ int main(int argc, char **argv) } int c; - while ((c = getopt (argc, argv, "--:O:c:F:g:hIL:m:M:n:N:o:P:r:R:s:S:x:y:z:")) != -1) { - + while ((c = getopt(argc, argv, "--:O:c:F:g:hIL:m:M:n:N:o:P:R:s:S:x:y:z:")) != -1) { /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ if (c == 1 || c == '-' || c == 'O') @@ -312,20 +309,6 @@ int main(int argc, char **argv) printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); break; - /* - case 'r': - ricean_factor = pow(10,-.1*atof(optarg)); - if (ricean_factor>1) { - printf("Ricean factor must be between 0 and 1\n"); - exit(-1); - } - break; - */ - - case 'r': - seed = atoi(optarg); - break; - case 'R': N_RB_DL = atoi(optarg); break; @@ -379,8 +362,10 @@ int main(int argc, char **argv) default: case 'h': - printf("%s -F input_filename -g channel_mod -h(elp) -I(nitial sync) -L log_lvl -n n_frames -M SSBs -n frames -N cell_id -o FO -P phase -r seed -R RBs -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant\n", - argv[0]); + printf( + "OAI_RNGSEED=xxx ./%s -F input_filename -g channel_mod -h(elp) -I(nitial sync) -L log_lvl -n n_frames -M SSBs -n frames " + "-N cell_id -o FO -P phase -R RBs -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant\n", + argv[0]); //printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); printf("-c SSB subcarrier offset\n"); //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); @@ -401,7 +386,6 @@ int main(int argc, char **argv) //printf("-O oversampling factor (1,2,4,8,16)\n"); //printf("-p Use extended prefix mode\n"); printf("-P PBCH phase, allowed values 0-3\n"); - printf("-r set the random number generator seed (default: 0 = current time)\n"); printf("-R N_RB_DL\n"); printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if not -S given. If -n 1, then just SNR is simulated\n"); printf("-S Ending SNR, runs from SNR0 to SNR1\n"); @@ -414,7 +398,7 @@ int main(int argc, char **argv) } } - randominit(seed); + randominit(); logInit(); set_glog(loglvl); @@ -543,7 +527,7 @@ int main(int argc, char **argv) nr_common_signal_procedures (gNB,frame,slot, &ssb_pdu[i]); - int samp = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); + int samp = get_samples_slot_timestamp(frame_parms, slot); for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { if (cyclic_prefix_type == 1) { apply_nr_rotation_TX(frame_parms, diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index aba532a80d..4dbac5dd7f 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -131,7 +131,7 @@ int main(int argc, char **argv){ sigaction(SIGINT, &sigint_action, &oldaction); get_softmodem_params()->sl_mode = 0; - double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0; + double SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0; double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs=-1, bw; int i, l, aa, aarx, trial, n_frames = 1, rx_prach_start; //, ntrials=1; c16_t **txdata; @@ -162,7 +162,7 @@ int main(int argc, char **argv){ exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } - randominit(0); + randominit(); int c; while ((c = getopt (argc, argv, "--:O:hHaA:Cc:l:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) { @@ -665,7 +665,7 @@ int main(int argc, char **argv){ UE->X_u); int prach_start = subframe * frame_parms->samples_per_subframe; - int slot_start = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); + int slot_start = get_samples_slot_timestamp(frame_parms, slot); c16_t *tx[frame_parms->nb_antennas_rx]; for (int i = 0; i < frame_parms->nb_antennas_rx; i++) tx[i] = txdata[i] + slot_start; @@ -728,14 +728,7 @@ int main(int argc, char **argv){ for (trial = 0; trial < n_frames && !stop; trial++) { if (input_fd == NULL) { - sigma2_dB = 10*log10((double)tx_lev) - SNR - 10*log10(N_RB_UL*12/N_ZC); - - if (n_frames==1) - printf("sigma2_dB %f (SNR %f dB) tx_lev_dB %f\n",sigma2_dB,SNR,10*log10((double)tx_lev)); - - //AWGN - sigma2 = pow(10,sigma2_dB/10); - // printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB); + double sigma2 = compute_noise_variance(tx_lev, N_ZC, N_RB_UL, 1, SNR, n_frames); if (awgn_flag == 0) { multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_frame, 0); diff --git a/openair1/SIMULATION/NR_PHY/psbchsim.c b/openair1/SIMULATION/NR_PHY/psbchsim.c index 17c3473eb8..49d07616c4 100644 --- a/openair1/SIMULATION/NR_PHY/psbchsim.c +++ b/openair1/SIMULATION/NR_PHY/psbchsim.c @@ -325,15 +325,13 @@ int main(int argc, char **argv) // int frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; - int seed = 0; - cpuf = get_cpu_freq_GHz(); if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) { exit_fun("[NR_PSBCHSIM] Error, configuration module init failed\n"); } - randominit(0); + randominit(); int c; while ((c = getopt(argc, argv, "--:O:c:hn:o:s:FIL:N:R:S:T:")) != -1) { @@ -456,7 +454,7 @@ int main(int argc, char **argv) } } - randominit(seed); + randominit(); logInit(); set_glog(loglvl); @@ -576,7 +574,7 @@ int main(int argc, char **argv) proc.frame_rx, proc.nr_slot_rx, sl_uerx->sl_config.sl_sync_source.rx_slss_id); - int slot_start = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); + int slot_start = get_samples_slot_timestamp(frame_parms, slot); c16_t *tx[frame_parms->nb_antennas_rx]; for (int i = 0; i < frame_parms->nb_antennas_rx; i++) tx[i] = UE_TX->common_vars.txData[i] + slot_start; diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 8c9f2961c4..db20b21b8f 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -96,7 +96,7 @@ int main(int argc, char **argv) sigaction(SIGINT, &sigint_action, &oldaction); int i;//,l; - double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; + double SNR, snr0 = -2.0, snr1 = 2.0; double cfo=0; uint8_t snr1set=0; double **s_re,**s_im,**r_re,**r_im; @@ -151,7 +151,7 @@ int main(int argc, char **argv) exit_fun("[NR_PUCCHSIM] Error, configuration module init failed\n"); } - randominit(0); + randominit(); logInit(); int c; @@ -566,15 +566,16 @@ int main(int argc, char **argv) // SNR Computation // standard says: SNR = S / N, where S is the total signal energy, N is the noise energy in the transmission bandwidth (i.e. N_RB_DL resource blocks) // txlev = S. - int txlev = signal_energy((int32_t *)&txdataF[0][startingSymbolIndex*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size); + + // Compute transmitter energy level + int symbol_offset = startingSymbolIndex * frame_parms->ofdm_symbol_size; + int symbol_length = frame_parms->ofdm_symbol_size; + double txlev = compute_tx_energy_level(txdataF, 1, symbol_offset, symbol_length, n_trials); // sigma2 is variance per dimension, so N/(N_RB*12) // so, sigma2 = N/(N_RB_DL*12) => (S/SNR)/(N_RB*12) int N_RB = (format == 0 || format == 1) ? 1 : nrofPRB; - sigma2_dB = 10*log10(txlev*(N_RB_DL/N_RB))-SNR; - sigma2 = pow(10.0,sigma2_dB/10.0); - - if (n_trials==1) printf("txlev %d (%f dB), offset %d, sigma2 %f ( %f dB)\n",txlev,10*log10(txlev),startingSymbolIndex*frame_parms->ofdm_symbol_size,sigma2,sigma2_dB); + double sigma2 = compute_noise_variance(txlev, N_RB_DL * 12, N_RB, 1, SNR, n_trials); for (int symb=0; symbframe_parms.symbols_per_slot;symb++) { if (symb= startingSymbolIndex+nrofSymbols) { @@ -648,7 +649,16 @@ int main(int argc, char **argv) gNB_I0_measurements(gNB, nr_slot_tx, 0, gNB->frame_parms.symbols_per_slot, rb_mask_ul); start_meas(&gNB->phy_proc_rx); - if (n_trials==1) printf("noise rxlev %d (%d dB), rxlev pucch %d dB sigma2 %f dB, SNR %f, TX %f, I0 (pucch) %d, I0 (avg) %d\n",rxlev,dB_fixed(rxlev),dB_fixed(rxlev_pucch),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12),gNB->measurements.n0_subband_power_tot_dB[startingPRB],gNB->measurements.n0_subband_power_avg_dB); + if (n_trials == 1) + printf("noise rxlev %d (%d dB), rxlev pucch %d dB sigma2 %f dB, SNR %f, TX %f, I0 (pucch) %d, I0 (avg) %d\n", + rxlev, + dB_fixed(rxlev), + dB_fixed(rxlev_pucch), + 10 * log10(sigma2), + SNR, + 10 * log10((double)txlev * UE->frame_parms.ofdm_symbol_size / 12), + gNB->measurements.n0_subband_power_tot_dB[startingPRB], + gNB->measurements.n0_subband_power_avg_dB); if(format==0){ nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu; nfapi_nr_pucch_pdu_t pucch_pdu; diff --git a/openair1/SIMULATION/NR_PHY/srssim.c b/openair1/SIMULATION/NR_PHY/srssim.c new file mode 100644 index 0000000000..c86ab2b6a9 --- /dev/null +++ b/openair1/SIMULATION/NR_PHY/srssim.c @@ -0,0 +1,690 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include "common/utils/nr/nr_common.h" +#include "common/utils/var_array.h" +#define inMicroS(a) (((double)(a)) / (get_cpu_freq_GHz() * 1000.0)) +#include "SIMULATION/LTE_PHY/common_sim.h" +#include "common/utils/assertions.h" +#include "PHY/INIT/nr_phy_init.h" +#include "PHY/MODULATION/nr_modulation.h" +#include "PHY/MODULATION/modulation_common.h" +#include "PHY/NR_REFSIG/ul_ref_seq_nr.h" +#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" +#include "PHY/NR_TRANSPORT/nr_transport_proto.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" +#include "PHY/NR_ESTIMATION/nr_ul_estimation.h" +#include "PHY/phy_vars_nr_ue.h" +#include "e1ap_messages_types.h" +#include "executables/nr-uesoftmodem.h" +#include "SIMULATION/NR_PHY/nr_unitary_defs.h" +#include "SIMULATION/TOOLS/sim.h" +#include "common/ran_context.h" +#include "time_meas.h" +#include "SCHED_NR/phy_frame_config_nr.h" + +PHY_VARS_gNB *gNB; +PHY_VARS_NR_UE *UE; +RAN_CONTEXT_t RC; +char *uecap_file = NULL; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + +double cpuf; +uint64_t downlink_frequency[MAX_NUM_CCs][4]; +uint64_t uplink_frequency[MAX_NUM_CCs][4]; +THREAD_STRUCT thread_struct; + +// needed for some functions +uint16_t n_rnti = 0x1234; +openair0_config_t openair0_cfg[MAX_CARDS]; +nrUE_params_t nrUE_params; + +nrUE_params_t *get_nrUE_params(void) +{ + return &nrUE_params; +} + +channel_desc_t *UE2gNB[MAX_MOBILES_PER_GNB][NUMBER_OF_gNB_MAX]; +configmodule_interface_t *uniqCfg = NULL; + +void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) +{ + abort(); +} +void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req) +{ + abort(); +} +void e1_bearer_release_cmd(const e1ap_bearer_release_cmd_t *cmd) +{ + abort(); +} + +int main(int argc, char *argv[]) +{ + stop = false; + __attribute__((unused)) struct sigaction oldaction; + sigaction(SIGINT, &sigint_action, &oldaction); + + double SNR, snr0 = 0, snr1 = 20.0; + double snr_step = 1; + uint8_t snr1set = 0; + double **s_re, **s_im, **r_re, **r_im; + int trial, n_trials = 1, delay = 0; + double maxDoppler = 0.0; + uint8_t n_tx = 1, n_rx = 1; + channel_desc_t *UE2gNB; + uint8_t extended_prefix_flag = 0; + SCM_t channel_model = AWGN; + corr_level_t corr_level = CORR_LEVEL_LOW; + uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; + int srs_start_symbol = 13; + int srs_comb_size = 0; + int srs_comb_offset = 0; + int srs_cyclic_shift = 0; + int nb_symb_srs = 0; + int i; + int loglvl = OAILOG_WARNING; + int print_perf = 0; + int slot = 8; + int frame = 1; + cpuf = get_cpu_freq_GHz(); + double DS_TDL = .03; + int threequarter_fs = 0; + uint64_t SSB_positions = 0x01; + uint16_t Nid_cell = 0; + + if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) { + exit_fun("[NR_SRSSIM] Error, configuration module init failed\n"); + } + + randominit(); + + /* initialize the sin-cos table */ + InitSinLUT(); + + int c; + while ((c = getopt(argc, argv, "--:O:a:b:c:d:e:f:g:h:i:kl:m:n:p:s:u:y:z:A:B:C:H:PR:S:L:")) != -1) { + /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ + /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ + if (c == 1 || c == '-' || c == 'O') + continue; + + printf("handling optarg %c\n", c); + switch (c) { + case 'a': + srs_start_symbol = atoi(optarg); + AssertFatal(srs_start_symbol >= 8 && srs_start_symbol <= 13, "start_symbol %d is not in 8..13\n", srs_start_symbol); + break; + + case 'b': + nb_symb_srs = atoi(optarg); + AssertFatal(nb_symb_srs == 1 || nb_symb_srs == 2 || nb_symb_srs == 4, + "number of srs symbols %d is not 1,2,4\n", + nb_symb_srs); + nb_symb_srs >>= 1; // Value: 0 = 1 symbol, 1 = 2 symbols, 2 = 4 symbols + break; + + case 'c': + n_rnti = atoi(optarg); + AssertFatal(n_rnti > 0 && n_rnti <= 65535, "Illegal n_rnti %x\n", n_rnti); + break; + + case 'd': + delay = atoi(optarg); + break; + + case 'e': + srs_comb_size = atoi(optarg); + AssertFatal(srs_comb_size >= 0 && srs_comb_size < 2, "comb_size %d is not in 0 or 1\n", srs_comb_size); + break; + + case 'f': + srs_comb_offset = atoi(optarg); + if (srs_comb_size == 0) { + AssertFatal(srs_comb_offset >= 0 && srs_comb_offset <= 1, "comb_offset %d is not in 0...1\n", srs_comb_offset); + } else if (srs_comb_size == 1) { + AssertFatal(srs_comb_offset >= 0 && srs_comb_offset <= 3, "comb_offset %d is not in 0...3\n", srs_comb_offset); + } + break; + + case 'g': + + switch ((char)*optarg) { + case 'A': + channel_model = TDL_A; + DS_TDL = 0.030; // 30 ns + printf("Channel model: TDLA30\n"); + break; + case 'B': + channel_model = TDL_B; + DS_TDL = 0.100; // 100ns + printf("Channel model: TDLB100\n"); + break; + case 'C': + channel_model = TDL_C; + DS_TDL = 0.300; // 300 ns + printf("Channel model: TDLC300\n"); + break; + default: + printf("Unsupported channel model!\n"); + exit(-1); + } + + if (optarg[1] == ',') { + switch (optarg[2]) { + case 'l': + corr_level = CORR_LEVEL_LOW; + break; + case 'm': + corr_level = CORR_LEVEL_MEDIUM; + break; + case 'h': + corr_level = CORR_LEVEL_HIGH; + break; + default: + printf("Invalid correlation level!\n"); + } + } + + if (optarg[3] == ',') { + maxDoppler = atoi(&optarg[4]); + printf("Maximum Doppler Frequency: %.0f Hz\n", maxDoppler); + } + break; + + case 'i': + srs_cyclic_shift = atoi(optarg); + if (srs_comb_size == 0) { + AssertFatal(srs_cyclic_shift >= 0 && srs_cyclic_shift <= 7, "comb_shift %d is not in 0...7\n", srs_cyclic_shift); + } else if (srs_comb_size == 1) { + AssertFatal(srs_cyclic_shift >= 0 && srs_cyclic_shift <= 11, "comb_shift %d is not in 0...11\n", srs_cyclic_shift); + } + break; + + case 'k': + printf("Setting threequarter_fs_flag\n"); + threequarter_fs = 1; + break; + + case 'n': + n_trials = atoi(optarg); + break; + + case 'p': + extended_prefix_flag = 1; + break; + + case 's': + snr0 = atof(optarg); + printf("Setting SNR0 to %f\n", snr0); + break; + + case 'u': + mu = atoi(optarg); + break; + + case 'y': + n_tx = atoi(optarg); + if ((n_tx == 0) || (n_tx > 4)) { + printf("Unsupported number of tx antennas %d\n", n_tx); + exit(-1); + } + break; + + case 'z': + n_rx = atoi(optarg); + if ((n_rx == 0) || (n_rx > 8)) { + printf("Unsupported number of rx antennas %d\n", n_rx); + exit(-1); + } + break; + + case 'H': + slot = atoi(optarg); + break; + + case 'R': + N_RB_DL = atoi(optarg); + N_RB_UL = N_RB_DL; + break; + + case 'S': + snr1 = atof(optarg); + snr1set = 1; + printf("Setting SNR1 to %f\n", snr1); + break; + + case 'P': + print_perf = 1; + cpu_meas_enabled = 1; + break; + + case 'L': + loglvl = atoi(optarg); + break; + + default: + case 'h': + printf("%s -h(elp)\n", argv[0]); + printf("-a SRS starting symbol (8 .. 13)\n"); + printf("-b SRS number of symbols (1, 2, 4)\n"); + printf("-c RNTI\n"); + printf("-d Introduce delay in terms of number of samples\n"); + printf("-e SRS comb size, 0 (comb size 2), 1 (comb size 4) \n"); + printf("-f SRS comb offset, 0 .. 1 (comb size 2), 0 .. 3 (comb size 4) \n"); + printf( + "-g Channel model configuration. Arguments list: Number of arguments = 3, {Channel model: [A] TDLA30, [B] TDLB100, [C] " + "TDLC300}, {Correlation: [l] Low, [m] Medium, [h] High}, {Maximum Doppler shift} e.g. -g A,l,10\n"); + printf("-h This message\n"); + printf("-i SRS cyclic shift, 0 .. 7 (comb size 2), 0 .. 11 (comb size 4) \n"); + printf("-k 3/4 sampling\n"); + printf("-n Number of trials to simulate\n"); + printf("-p Use extended prefix mode\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-u Set the numerology\n"); + printf("-y Number of TX antennas used at UE\n"); + printf("-z Number of RX antennas used at gNB\n"); + printf("-H Slot number\n"); + printf("-L \n"); + printf("-P Print SRS performances\n"); + printf("-R Maximum number of available resorce blocks (N_RB_DL)\n"); + exit(-1); + break; + } + } + + logInit(); + set_glog(loglvl); + + int ret = 1; + + if (snr1set == 0) + snr1 = snr0 + 10; + + double sampling_rate, tx_bandwidth, rx_bandwidth; + uint32_t samples; + get_samplerate_and_bw(mu, N_RB_DL, threequarter_fs, &sampling_rate, &samples, &tx_bandwidth, &rx_bandwidth); + + // Initialize gNB + gNB = calloc_or_fail(1, sizeof(PHY_VARS_gNB)); + gNB->ofdm_offset_divisor = UINT_MAX; + gNB->RU_list[0] = calloc_or_fail(1, sizeof(**gNB->RU_list)); + gNB->RU_list[0]->rfdevice.openair0_cfg = openair0_cfg; + + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + fp->N_RB_DL = N_RB_DL; + fp->N_RB_UL = N_RB_UL; + fp->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; + fp->nb_antennas_tx = n_tx; + fp->nb_antennas_rx = n_rx; + fp->threequarter_fs = threequarter_fs; + nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions); + printf("dl freq %" PRIu64 " , ul freq %" PRIu64 " \n", fp->dl_CarrierFreq, fp->ul_CarrierFreq); + do_tdd_config_sim(gNB, mu); + phy_init_nr_gNB(gNB); + + // Initialize UE + UE = calloc_or_fail(1, sizeof(PHY_VARS_NR_UE)); + memcpy(&UE->frame_parms, fp, sizeof(NR_DL_FRAME_PARMS)); // setting same frame parameters as gNB + + /* RU handles rxdataF, and gNB just has a pointer. Here, we don't have an RU, + * so we need to allocate that memory as well. First index in rxdataF[0] index refers to beams*/ + for (i = 0; i < n_rx; i++) + gNB->common_vars.rxdataF[0][i] = malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); + + /* no RU: need to have rxdata */ + c16_t **rxdata; + rxdata = malloc_or_fail(n_rx * sizeof(*rxdata)); + for (i = 0; i < n_rx; i++) + rxdata[i] = malloc16_clear(fp->samples_per_frame * sizeof(c16_t)); + + /* no memory allocated for UE common_vars: need to have txdata and txdataF */ + c16_t **txdata; + txdata = malloc_or_fail(n_tx * sizeof(*txdata)); + for (i = 0; i < n_tx; i++) + txdata[i] = malloc16_clear(fp->samples_per_frame * sizeof(c16_t)); + + c16_t **txdataF; + txdataF = malloc_or_fail(n_tx * sizeof(*txdataF)); + for (i = 0; i < n_tx; i++) + txdataF[i] = malloc16_clear(fp->samples_per_frame_wCP * sizeof(c16_t)); + + // Configure channel model + UE2gNB = new_channel_desc_scm(n_tx, + n_rx, + channel_model, + sampling_rate / 1e6, + fp->ul_CarrierFreq, + tx_bandwidth, + DS_TDL, + maxDoppler, + corr_level, + 0, + delay, + 0, + 0); + + if (UE2gNB == NULL) { + printf("Problem generating channel model. Exiting.\n"); + exit(-1); + } + + // Allocate memory to intermediate variables to apply channel + int slot_length = get_samples_per_slot(slot, fp); + + s_re = malloc_or_fail(n_tx * sizeof(double *)); + s_im = malloc_or_fail(n_tx * sizeof(double *)); + r_re = malloc_or_fail(n_rx * sizeof(double *)); + r_im = malloc_or_fail(n_rx * sizeof(double *)); + + for (int aatx = 0; aatx < n_tx; aatx++) { + s_re[aatx] = calloc_or_fail(1, slot_length * sizeof(double)); + s_im[aatx] = calloc_or_fail(1, slot_length * sizeof(double)); + } + + for (int aarx = 0; aarx < n_rx; aarx++) { + r_re[aarx] = calloc_or_fail(1, slot_length * sizeof(double)); + r_im[aarx] = calloc_or_fail(1, slot_length * sizeof(double)); + } + + //----------- configure SRS ---------------------------- + long locationAndBandwidth = PRBalloc_to_locationandbandwidth(N_RB_DL, 0); + + // Configure SRS parameters at gNB + const uint16_t m_SRS[64] = {4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 48, 52, 56, + 60, 64, 72, 72, 76, 80, 88, 96, 96, 104, 112, 120, 120, 120, 128, 128, + 128, 132, 136, 144, 144, 144, 144, 152, 160, 160, 160, 168, 176, 184, 192, 192, + 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256, 256, 264, 272, 272, 272}; + nfapi_nr_srs_pdu_t srs_pdu = {.rnti = n_rnti, + .bwp_size = NRRIV2BW(locationAndBandwidth, 275), + .bwp_start = NRRIV2PRBOFFSET(locationAndBandwidth, 275), + .subcarrier_spacing = fp->numerology_index, + .cyclic_prefix = extended_prefix_flag, + .num_ant_ports = n_tx == 4 ? 2 + : n_tx == 2 ? 1 + : 0, + .num_symbols = nb_symb_srs, + .num_repetitions = 0, // Value: 0 = 1, 1 = 2, 2 = 4 + .time_start_position = fp->symbols_per_slot - 1 - srs_start_symbol, + .bandwidth_index = 0, + .config_index = rrc_get_max_nr_csrs(srs_pdu.bwp_size, srs_pdu.bandwidth_index), + .sequence_id = 40, + .comb_size = srs_comb_size, + .comb_offset = srs_comb_offset, + .cyclic_shift = srs_cyclic_shift, + .frequency_position = 0, + .frequency_shift = 0, + .frequency_hopping = 0, + .group_or_sequence_hopping = 0, + .resource_type = NR_SRS_Resource__resourceType_PR_periodic, + .t_srs = 1, + .t_offset = 0, + .srs_parameters_v4.srs_bandwidth_size = m_SRS[srs_pdu.config_index], + .srs_parameters_v4.usage = 1 << NR_SRS_ResourceSet__usage_codebook, + .srs_parameters_v4.report_type[0] = 1, + .srs_parameters_v4.iq_representation = 1, + .srs_parameters_v4.prg_size = 1, + .srs_parameters_v4.num_total_ue_antennas = 1 << srs_pdu.num_ant_ports, + .beamforming.num_prgs = m_SRS[srs_pdu.config_index], + .beamforming.prg_size = 1}; + + gNB->srs->srs_pdu = srs_pdu; + gNB->srs->active = true; + gNB->srs->beam_nb = 0; + gNB->srs->frame = frame; + gNB->srs->slot = slot; + + // Configure SRS parameters at UE + fapi_nr_ul_config_srs_pdu srs_config_pdu = {.rnti = srs_pdu.rnti, + .bwp_size = srs_pdu.bwp_size, + .bwp_start = srs_pdu.bwp_start, + .subcarrier_spacing = srs_pdu.subcarrier_spacing, + .cyclic_prefix = srs_pdu.cyclic_prefix, + .num_ant_ports = srs_pdu.num_ant_ports, + .num_symbols = srs_pdu.num_symbols, + .num_repetitions = srs_pdu.num_repetitions, + .time_start_position = srs_pdu.time_start_position, + .bandwidth_index = srs_pdu.bandwidth_index, + .config_index = srs_pdu.config_index, + .sequence_id = srs_pdu.sequence_id, + .comb_size = srs_pdu.comb_size, + .comb_offset = srs_pdu.comb_offset, + .cyclic_shift = srs_pdu.cyclic_shift, + .frequency_position = srs_pdu.frequency_position, + .frequency_shift = srs_pdu.frequency_shift, + .frequency_hopping = srs_pdu.frequency_hopping, + .group_or_sequence_hopping = srs_pdu.group_or_sequence_hopping, + .resource_type = srs_pdu.resource_type, + .t_srs = srs_pdu.t_srs, + .t_offset = srs_pdu.t_offset, + .beamforming.num_prgs = srs_pdu.beamforming.num_prgs, + .beamforming.prg_size = srs_pdu.beamforming.prg_size}; + + nr_phy_data_tx_t phy_data = {0}; + phy_data.srs_vars.active = true; + phy_data.srs_vars.srs_config_pdu = srs_config_pdu; + UE->nr_srs_info = malloc16_clear(sizeof(nr_srs_info_t)); + + //----------- UE TX SRS procedures --------------------- + + UE_nr_rxtx_proc_t proc; + proc.frame_rx = frame; + proc.frame_tx = frame; + proc.nr_slot_tx = slot; + proc.nr_slot_rx = slot; + bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = {0}; + int slot_offset = get_samples_slot_timestamp(fp, slot); + uint16_t ofdm_symbol_size = fp->ofdm_symbol_size; + int slot_offsetF = (slot % RU_RX_SLOT_DEPTH) * fp->symbols_per_slot * ofdm_symbol_size; + + c16_t *txF[n_tx]; + for (i = 0; i < n_tx; i++) + txF[i] = txdataF[i] + slot_offsetF; + + c16_t *txd[n_tx]; + for (i = 0; i < n_tx; i++) + txd[i] = txdata[i] + slot_offset; + + ue_srs_procedures_nr(UE, &proc, (c16_t **)txF, &phy_data, was_symbol_used); + + //------------ TX rotation and OFDM Modulation -------------------------- + nr_tx_rotation_and_ofdm_mod(slot, fp, n_tx, txF, txd, link_type_ul, was_symbol_used, false); + + //----------- Apply propagation channel and add noise ---------------------------- + + double ts = 1.0 / (fp->subcarrier_spacing * ofdm_symbol_size); + + for (i = 0; i < slot_length; i++) { + for (int aa = 0; aa < n_tx; aa++) { + s_re[aa][i] = (double)txdata[aa][slot_offset + i].r; + s_im[aa][i] = (double)txdata[aa][slot_offset + i].i; + } + } + + // Compute SRS symbol offset and length + int symbol_offset = slot_offset; + int abs_first_symbol = slot * fp->symbols_per_slot; + int idx_sym; + for (idx_sym = abs_first_symbol; idx_sym < abs_first_symbol + srs_start_symbol; idx_sym++) + symbol_offset += (idx_sym % (0x7 << fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0; + + symbol_offset += ofdm_symbol_size * srs_start_symbol; + int symbol_length = ofdm_symbol_size + (idx_sym % (0x7 << fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0; + + // Compute transmitter energy level + double txlev_sum = compute_tx_energy_level(txdata, n_tx, symbol_offset, symbol_length, n_trials); + + for (SNR = snr0; SNR <= snr1 && !stop; SNR += snr_step) { + varArray_t *table_rx = initVarArray(1000, sizeof(double)); + reset_meas(&gNB->rx_srs_stats); + reset_meas(&gNB->generate_srs_stats); + reset_meas(&gNB->get_srs_signal_stats); + reset_meas(&gNB->srs_channel_estimation_stats); + reset_meas(&gNB->srs_timing_advance_stats); + + double sum_srs_snr = 0; + int tao_ns_count = 0; + for (trial = 0; trial < n_trials && !stop; trial++) { + // Estimate noise power from the transmitter level and SNR + double sigma = compute_noise_variance(txlev_sum, ofdm_symbol_size, srs_pdu.bwp_size, 1, SNR, n_trials); + + //----------- Apply propagation channel ---------------------------- + multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0); + + //----------- Add noise ---------------------------- + add_noise(rxdata, + (const double **)r_re, + (const double **)r_im, + sigma, // noise power + slot_length, + slot_offset, + ts, + 0, // delay + 0, // pdu_bit_map + 0, // PTRS_BITMAP, + n_rx); + + //----------- OFDM Demodulation and RX rotation-------------------------- + nr_ofdm_demod_and_rx_rotation(rxdata, + gNB->common_vars.rxdataF[0], + fp, + n_rx, + slot, + slot_offsetF, + link_type_ul, + was_symbol_used); + + //----------- UE RX SRS procedures --------------------- + + start_meas(&gNB->rx_srs_stats); + NR_gNB_SRS_t *srs = &gNB->srs[0]; + uint8_t N_symb_SRS = 1 << srs->srs_pdu.num_symbols; + uint8_t N_ap = 1 << srs->srs_pdu.num_ant_ports; + int16_t snr_per_rb[srs->srs_pdu.bwp_size]; + uint16_t timing_advance_offset; + int16_t timing_advance_offset_nsec[n_rx]; + int srs_est; + c16_t srs_estimated_channel_freq[n_rx][N_ap][ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32))); + c16_t srs_estimated_channel_time[n_rx][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size] __attribute__((aligned(32))); + + nr_srs_rx_procedures(gNB, + frame, + slot, + n_rx, + N_ap, + N_symb_SRS, + ofdm_symbol_size, + srs, + gNB->nr_srs_info[0], + &srs_est, + srs_estimated_channel_freq, + srs_estimated_channel_time, + snr_per_rb, + &timing_advance_offset, + timing_advance_offset_nsec); + + sum_srs_snr += pow(10, (double)gNB->srs->snr / 10.0); + + int16_t delay_ns = delay * 1e9 / (fp->samples_per_frame * 100); + for (int ant_idx = 0; ant_idx < n_rx; ant_idx++) { + if (n_trials == 1) + printf("[RX ant %d] SRS estimated: TA offset %d, TA offset ns %d \n", + ant_idx, + timing_advance_offset, + timing_advance_offset_nsec[ant_idx]); + if (timing_advance_offset_nsec[ant_idx] == delay_ns) + tao_ns_count++; + } + stop_meas(&gNB->rx_srs_stats); + } // trail loop + float tao_ns_rate = (float)tao_ns_count / (n_trials * n_rx); + float SRS_SNR_dB = 10 * log10(sum_srs_snr / n_trials); + printf("Actual SNR : %f, Estimated SNR from SRS %f (dB), TA offset success rate %f %%\n", SNR, SRS_SNR_dB, tao_ns_rate * 100); + + if (print_perf == 1) { + printf("\ngNB RX\n"); + printDistribution(&gNB->rx_srs_stats, table_rx, "RX SRS time"); + printStatIndent(&gNB->generate_srs_stats, "Generate SRS sequence time"); + printStatIndent(&gNB->get_srs_signal_stats, "Get SRS signal time"); + printStatIndent(&gNB->srs_channel_estimation_stats, "SRS channel estimation time"); + printStatIndent(&gNB->srs_timing_advance_stats, "SRS timing advance estimation time"); + printf("\n"); + } + + free(table_rx); + + int srs_ret = 1; + if (SNR > 30 && SRS_SNR_dB > 30) { + srs_ret = 0; + } else if (SNR >= SRS_SNR_dB) { + srs_ret = SRS_SNR_dB >= 0.7 * SNR ? 0 : 1; + } else if (SRS_SNR_dB > SNR) { + srs_ret = SNR >= 0.7 * SRS_SNR_dB ? 0 : 1; + } + + if (tao_ns_rate > 0.9 && srs_ret == 0) { + ret = 0; + break; + } + + } // SNR loop + + printf("*************\n"); + printf("SRS test %s\n", ret == 0 ? "OK" : "FAILED"); + printf("*************\n"); + + // free memory + + for (i = 0; i < n_tx; i++) { + free(s_re[i]); + free(s_im[i]); + free(txdata[i]); + free(txdataF[i]); + } + free(s_re); + free(s_im); + free(txdata); + free(txdataF); + + for (i = 0; i < n_rx; i++) { + free(r_re[i]); + free(r_im[i]); + free(rxdata[i]); + free(gNB->common_vars.rxdataF[0][i]); + } + + free(r_re); + free(r_im); + free(rxdata); + + phy_free_nr_gNB(gNB); + free_channel_desc_scm(UE2gNB); + free_and_zero(UE->nr_srs_info); + free(gNB->RU_list[0]); + free(UE); + + return ret; +} diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 77a0046e1f..3705df3b2c 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -139,7 +139,7 @@ int main(int argc, char **argv) } //logInit(); - randominit(0); + randominit(); int c; while ((c = getopt(argc, argv, "--:O:hg:n:s:S:py:z:M:N:R:F:m:l:q:r:W:")) != -1) { diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 85c165b00d..d7bd25555f 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -120,6 +120,15 @@ void nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t { } +/* this is a hack, but necessary for E2 agent. We compile in all of RRC + * (because of CMakeLists.txt), but we don't need it (only nr_radio_config.c). + * however, if E2 agent is defined, the following functions are used in + * rrc_gNB.c, but defined in RAN functions. In order to avoid pulling this in + * here as well, only provide a prototype (and abort if they are ever called). */ +void signal_rrc_msg(void /*const nr_rrc_class_e nr_channel, const uint32_t rrc_msg_id, const byte_array_t rrc_ba*/ ) { abort(); } +void signal_rrc_state_changed_to(void /* const gNB_RRC_UE_t *rrc_ue_context, const rrc_state_e2sm_rc_e rrc_state */) { abort(); } +void signal_ue_id(void /* const gNB_RRC_UE_t *rrc_ue_context, const uint16_t class, const uint32_t msg_id */) { abort(); } + extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { abort(); } @@ -272,7 +281,6 @@ int main(int argc, char *argv[]) char *filename_csv = NULL; int i; double SNR, snr0 = -2.0, snr1 = 2.0; - double sigma, sigma_dB; double snr_step = .2; uint8_t snr1set = 0; int slot = 8, frame = 1; @@ -299,7 +307,7 @@ int main(int argc, char *argv[]) int Imcs = 9; uint8_t precod_nbr_layers = 1; int tx_offset; - int32_t txlev_sum = 0, atxlev[4]; + double txlev_sum = 0; int start_rb = 0; int UE_id = 0; int print_perf = 0; @@ -348,7 +356,7 @@ int main(int argc, char *argv[]) } int ul_proc_error = 0; // uplink processing checking status flag //logInit(); - randominit(0); + randominit(); /* initialize the sin-cos table */ InitSinLUT(); @@ -1052,8 +1060,8 @@ int main(int argc, char *argv[]) //for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0)); int read_errors=0; - int slot_offset = gNB->frame_parms.get_samples_slot_timestamp(slot, &gNB->frame_parms, 0); - int slot_length = slot_offset - gNB->frame_parms.get_samples_slot_timestamp(slot - 1, &gNB->frame_parms, 0); + int slot_offset = get_samples_slot_timestamp(&gNB->frame_parms, slot); + int slot_length = slot_offset - get_samples_slot_timestamp(&gNB->frame_parms, slot - 1); if (input_fd != NULL) { // 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s, @@ -1264,7 +1272,7 @@ int main(int argc, char *argv[]) srs_pdu->subcarrier_spacing = gNB->frame_parms.subcarrier_spacing; srs_pdu->num_ant_ports = n_tx == 4 ? 2 : n_tx == 2 ? 1 : 0; srs_pdu->sequence_id = 40; - srs_pdu->time_start_position = gNB->frame_parms.symbols_per_slot - 1; + srs_pdu->time_start_position = 0; srs_pdu->config_index = rrc_get_max_nr_csrs(srs_pdu->bwp_size, srs_pdu->bandwidth_index); srs_pdu->resource_type = NR_SRS_Resource__resourceType_PR_periodic; srs_pdu->t_srs = 1; @@ -1362,6 +1370,7 @@ int main(int argc, char *argv[]) srs_config_pdu->sequence_id = 40; srs_config_pdu->resource_type = NR_SRS_Resource__resourceType_PR_periodic; srs_config_pdu->t_srs = 1; + srs_config_pdu->time_start_position = 0; } for (int i = 0; i < (TBS / 8); i++) @@ -1373,7 +1382,7 @@ int main(int argc, char *argv[]) /////////////////////////phy_procedures_nr_ue_TX/////////////////////// /////////// - int slot_start = UE->frame_parms.get_samples_slot_timestamp(slot, &UE->frame_parms, 0); + int slot_start = get_samples_slot_timestamp(&UE->frame_parms, slot); c16_t *tx[UE->frame_parms.nb_antennas_tx]; for (int i = 0; i < UE->frame_parms.nb_antennas_tx; i++) tx[i] = UE->common_vars.txData[i] + slot_start; @@ -1391,36 +1400,22 @@ int main(int argc, char *argv[]) } /////////// //////////////////////////////////////////////////// - tx_offset = gNB->frame_parms.get_samples_slot_timestamp(slot, &gNB->frame_parms, 0); - txlev_sum = 0; - for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) { - atxlev[aa] = - signal_energy((int32_t *)&UE->common_vars - .txData[aa][tx_offset + 5 * gNB->frame_parms.ofdm_symbol_size - + 4 * gNB->frame_parms.nb_prefix_samples + gNB->frame_parms.nb_prefix_samples0], - gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.nb_prefix_samples); - - txlev_sum += atxlev[aa]; - - if (n_trials == 1) - printf("txlev[%d] = %d (%f dB) txlev_sum %d\n", aa, atxlev[aa], 10 * log10((double)atxlev[aa]), txlev_sum); - } + // Compute transmitter energy level + tx_offset = get_samples_slot_timestamp(&gNB->frame_parms, slot); + int symbol_offset = tx_offset + 5 * gNB->frame_parms.ofdm_symbol_size + 4 * gNB->frame_parms.nb_prefix_samples + + gNB->frame_parms.nb_prefix_samples0; + int symbol_length = gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.nb_prefix_samples; + txlev_sum = compute_tx_energy_level(UE->common_vars.txData, + UE->frame_parms.nb_antennas_tx, + symbol_offset, + symbol_length, + n_trials); } else n_trials = 1; if (input_fd == NULL) { - // Justification of division by precod_nbr_layers: - // When the channel is the identity matrix, the results in terms of SNR should be almost equal for 2x2 and 4x4. - sigma_dB = - 10 * log10((double)txlev_sum / precod_nbr_layers * ((double)gNB->frame_parms.ofdm_symbol_size / (12 * nb_rb))) - SNR; - sigma = pow(10, sigma_dB / 10); - - if (n_trials == 1) - printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n", - sigma, - sigma_dB, - 10 * log10((double)txlev_sum), - (double)(double)gNB->frame_parms.ofdm_symbol_size / (12 * nb_rb)); + double sigma = + compute_noise_variance(txlev_sum, gNB->frame_parms.ofdm_symbol_size, nb_rb, precod_nbr_layers, SNR, n_trials); for (i = 0; i < slot_length; i++) { for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) { @@ -1451,26 +1446,20 @@ int main(int argc, char *argv[]) UL_INFO.crc_ind.number_crcs = 0; UL_INFO.srs_ind.number_of_pdus = 0; - for(uint8_t symbol = 0; symbol < (gNB->frame_parms.Ncp == EXTENDED ? 12 : 14); symbol++) { - for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) - nr_slot_fep_ul(&gNB->frame_parms, - (int32_t *)rxdata[aa], - (int32_t *)gNB->common_vars.rxdataF[0][aa], - symbol, - slot, - 0); - } + //----------- OFDM Demodulation and RX rotation-------------------------- + bool was_symbol_used[14] = {0}; int offset = (slot & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; - for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { - const unsigned int max_symb = (gNB->frame_parms.Ncp == EXTENDED) ? 12 : 14; - for (int sym = 0; sym < max_symb; sym++) - apply_nr_rotation_symbol_RX(&gNB->frame_parms, - gNB->common_vars.rxdataF[0][aa] + offset + sym * gNB->frame_parms.ofdm_symbol_size, - gNB->frame_parms.symbol_rotation[1], - gNB->frame_parms.N_RB_UL, - slot, - sym); + for (int i = 0; i < 14; i++) { + was_symbol_used[i] = true; } + nr_ofdm_demod_and_rx_rotation(rxdata, + gNB->common_vars.rxdataF[0], + &gNB->frame_parms, + gNB->frame_parms.nb_antennas_rx, + slot, + offset, + link_type_ul, + was_symbol_used); ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot, &UL_INFO); @@ -1733,7 +1722,7 @@ int main(int argc, char *argv[]) printStatIndent2(&gNB->rx_pusch_symbol_processing_stats, "RX PUSCH Symbol Processing time"); printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time"); printStatIndent2(&gNB->ts_deinterleave, "ULSCH segment deinterleaving time"); - printStatIndent2(&gNB->ts_rate_unmatch, "ULSCH segment rate recovery time"); + printStatIndent2(&gNB->ts_rate_unmatch, "ULSCH segment rate matching time"); printStatIndent2(&gNB->ts_ldpc_decode, "ULSCH segments decoding time"); printStatIndent(&gNB->rx_srs_stats,"RX SRS time"); printStatIndent2(&gNB->generate_srs_stats,"Generate SRS sequence time"); diff --git a/openair1/SIMULATION/RF/rf.c b/openair1/SIMULATION/RF/rf.c index 081a102bbb..e9b49ed8f2 100644 --- a/openair1/SIMULATION/RF/rf.c +++ b/openair1/SIMULATION/RF/rf.c @@ -248,7 +248,7 @@ int main(int argc, char* argv[]) channel_desc_t *channel; srand(0); - randominit(0); + randominit(); set_taus_seed(0); channel = new_channel_desc_scm(nb_antennas, diff --git a/openair1/SIMULATION/TOOLS/ch_desc_proto.c b/openair1/SIMULATION/TOOLS/ch_desc_proto.c index b1e71fcfb4..dbc77a9b9b 100644 --- a/openair1/SIMULATION/TOOLS/ch_desc_proto.c +++ b/openair1/SIMULATION/TOOLS/ch_desc_proto.c @@ -93,7 +93,7 @@ int main() { {3420,2820},{1580,3940},{660,2100},{2740,1180},{2500,2500}, {3580,3580},{3740,3140},{3020,3020},{4340,4140},{980,4300} }; - randominit(0); + randominit(); ///////////////////////////////////////////////////////////////////////////////////////////////// int tabl_len=0; double local_table[MCS_COUNT][9][9]; diff --git a/openair1/SIMULATION/TOOLS/multipath_channel.c b/openair1/SIMULATION/TOOLS/multipath_channel.c index f17c2166a3..aeaa4f811f 100644 --- a/openair1/SIMULATION/TOOLS/multipath_channel.c +++ b/openair1/SIMULATION/TOOLS/multipath_channel.c @@ -68,7 +68,7 @@ void __attribute__ ((no_sanitize_address)) multipath_channel(channel_desc_t *des #ifdef DEBUG_CH - for (l = 0; l<(int)desc->channel_length; l++) { + for (int l = 0; l<(int)desc->channel_length; l++) { printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y); } @@ -168,7 +168,7 @@ void __attribute__ ((no_sanitize_address)) multipath_channel(channel_desc_t *des } #ifdef DEBUG_CH - for (l = 0; l<(int)desc->channel_length; l++) { + for (int l = 0; l<(int)desc->channel_length; l++) { printf("ch[%i] = (%f, %f)\n", l, desc->ch[0][l].r, desc->ch[0][l].i); } #endif diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index d13cfd8921..cf973f5d84 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -48,8 +48,8 @@ static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt); static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt); static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt); int get_modchannel_index(char *buf, int debug, void *vdata, telnet_printfunc_t prnt); -int get_channel_params(char *buf, int debug, void *tdata, telnet_printfunc_t prnt); -int get_currentchannels_type(char *buf, int debug, void *vdata, telnet_printfunc_t prnt); +int get_channel_params(const char *buf, int debug, void *tdata, telnet_printfunc_t prnt); +int get_currentchannels_type(const char *buf, int debug, void *vdata, telnet_printfunc_t prnt); #define HELP_WEBIF_MODIFCHAN_STRING "" static telnetshell_cmddef_t channelmod_cmdarray[] = { @@ -462,8 +462,7 @@ void get_cexp_doppler(struct complexd *cexp_doppler, channel_desc_t *chan_desc, // TS 38.104 - Table G.3-1 uint16_t Dmin = 2; uint16_t Ds = 300; - double c = 299792458; - double v = chan_desc->max_Doppler * (c / (double)chan_desc->center_freq); + double v = chan_desc->max_Doppler * ((double) SPEED_OF_LIGHT / (double)chan_desc->center_freq); #ifdef DOPPLER_DEBUG printf("v = %f\n", v); @@ -572,11 +571,6 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, double path_loss_dB, float noise_power_dB) { - // To create tables for normal distribution - struct timespec t; - clock_gettime(CLOCK_MONOTONIC, &t); - tableNor((long) (t.tv_nsec % INT_MAX)); - channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t)); for(int i=0; imodel_name,modelname) == 0) @@ -2034,7 +2028,7 @@ static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt static char *pnames[] = {"riceanf", "aoa", "randaoa", "ploss", "noise_power_dB", "offset", "forgetf", NULL}; static char *pformat[] = {"%lf", "%lf", "%i", "%lf", "%lf", "%i", "%lf", NULL}; -int get_channel_params(char *buf, int debug, void *vdata, telnet_printfunc_t prnt) +int get_channel_params(const char *buf, int debug, void *vdata, telnet_printfunc_t prnt) { if (buf == NULL) { LOG_I(UTIL, "%s received NULL buffer\n", __FUNCTION__); @@ -2116,7 +2110,7 @@ static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_ } } -int get_currentchannels_type(char *buf, int debug, void *vdata, telnet_printfunc_t prnt) +int get_currentchannels_type(const char *buf, int debug, void *vdata, telnet_printfunc_t prnt) { webdatadef_t *tdata; if (buf == NULL) { diff --git a/openair1/SIMULATION/TOOLS/rangen_double.c b/openair1/SIMULATION/TOOLS/rangen_double.c index 54871448a4..9c38e33ce9 100644 --- a/openair1/SIMULATION/TOOLS/rangen_double.c +++ b/openair1/SIMULATION/TOOLS/rangen_double.c @@ -25,6 +25,7 @@ #include "sim.h" +static inline void tableNor(unsigned long seed); static unsigned int urseed, iy, ir[98]; /// uniformrandom static bool tableNordDone = false; /// gaussZiggurat @@ -49,14 +50,23 @@ void fill_random(void *buf, size_t sz) static const unsigned int a = 1664525lu; /*!\brief Initialization routine for Uniform/Gaussian random number generators. */ -void randominit(unsigned long seed_init) +// fix seed number by env variable OAI_RNGSEED +void randominit() { - unsigned long seed = seed_init; - if (seed_init == 0) - fill_random(&seed, sizeof(seed)); + unsigned long seed; const char* str_oai_rngseed = getenv("OAI_RNGSEED"); - if (str_oai_rngseed != NULL) - seed = atoi(str_oai_rngseed); + if (str_oai_rngseed != NULL) { + char *end; + seed = strtoul(str_oai_rngseed, &end, 0); /* 0: any base in hex, dec, oct */ + AssertFatal(*end == '\0' || *end == '\n', + "could not read seed %s at char '%c' (%d), pos %ld\n", + str_oai_rngseed, + *end, + *end, + end - str_oai_rngseed); + } else { + fill_random(&seed, sizeof(seed)); + } printf("Initializing random number generator, seed %lu\n", seed); // initialize uniformrandom RNG @@ -71,7 +81,6 @@ void randominit(unsigned long seed_init) // initialize gaussZiggurat RNG tableNor(seed); - tableNordDone = true; } /* @@ -164,7 +173,7 @@ double nfix(void) } /*!Procedure to create tables for normal distribution kn,wn and fn. */ -void tableNor(unsigned long seed) +static inline void tableNor(unsigned long seed) { jsr = seed; double dn = 3.442619855899; @@ -194,12 +203,11 @@ void tableNor(unsigned long seed) double __attribute__ ((no_sanitize("address", "undefined"))) gaussZiggurat(double mean, double variance) { - if (!tableNordDone) { - // let's make reasonnable constant tables - unsigned long seed; - fill_random(&seed, sizeof(seed)); - tableNor(seed); + if (!__builtin_expect(tableNordDone, 1)) { + fprintf(stderr, "%s(): RNG not initialized, run randominit() first\n", __func__); + abort(); } + hz = SHR3; iz = hz & 127; return hz != INT32_MIN && abs(hz) < kn[iz] ? hz * wn[iz] : nfix(); diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h index 359df00b55..6e60ce76de 100644 --- a/openair1/SIMULATION/TOOLS/sim.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -347,7 +347,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, double path_loss_dB, float noise_power_dB); -channel_desc_t *find_channel_desc_fromname( char *modelname ); +channel_desc_t *find_channel_desc_fromname(const char *modelname); /** @@ -528,10 +528,9 @@ int gauss(unsigned int *gauss_LUT,unsigned char Nbits); void fill_random(void *buf, size_t sz); double gaussdouble(double,double); -void randominit(unsigned long seed_init); +void randominit(); // fix seed number by env variable OAI_RNGSEED double uniformrandom(void); double gaussZiggurat(double mean, double variance); -void tableNor(unsigned long seed); int freq_channel(channel_desc_t *desc,uint16_t nb_rb, int16_t n_samples,int scs); int init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples,int scs); void term_freq_channel(void); diff --git a/openair1/SIMULATION/tests/CMakeLists.txt b/openair1/SIMULATION/tests/CMakeLists.txt index 566028234d..0c2ab8dd39 100644 --- a/openair1/SIMULATION/tests/CMakeLists.txt +++ b/openair1/SIMULATION/tests/CMakeLists.txt @@ -341,6 +341,27 @@ add_physim_test(physim.5g.nr_prachsim.test8 "15kHz SCS, 25 PRBs" nr_prachsim -a add_physim_test(physim.5g.nr_psbchsim.test1 "SLSS Search" nr_psbchsim -I) add_physim_test(physim.5g.nr_psbchsim.test2 "PSBCH TxRx" nr_psbchsim -n 30) +#################################################################################### +###### nr_srssim unit test ###### +#################################################################################### + +add_physim_test(physim.5g.nr_srssim.test1 "SRS: 30KHz SCS, 106 PRBs, ToA 24, Combsize 2" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 24) +add_physim_test(physim.5g.nr_srssim.test2 "SRS: 30KHz SCS, 106 PRBs, ToA 15, Combsize 2, Threequarter sampling" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 15 -k) +add_physim_test(physim.5g.nr_srssim.test3 "SRS: 30KHz SCS, 217 PRBs, ToA 8, Combsize 2" nr_srssim -n300 -R217 -s0 -S5 -y2 -z2 -d 8) +add_physim_test(physim.5g.nr_srssim.test4 "SRS: 30KHz SCS, 273 PRBs, TOA 30, Combsize 2" nr_srssim -n300 -R273 -s0 -S5 -y2 -z2 -d 30) +add_physim_test(physim.5g.nr_srssim.test5 "SRS: 30KHz SCS, 106 PRBs, ToA 16, Combsize 2, Cyclic shift 3" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 16 -i 1) +add_physim_test(physim.5g.nr_srssim.test6 "SRS: 30KHz SCS, 106 PRBs, ToA 23, Combsize 2, Comb offset 1" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 23 -f 1) +add_physim_test(physim.5g.nr_srssim.test7 "SRS: 30KHz SCS, 106 PRBs, ToA 8, Combsize 2, Symbol start 9" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 8 -a 9) +add_physim_test(physim.5g.nr_srssim.test8 "SRS: 120KHz SCS, 32 PRBs, ToA 19, Combsize 2" nr_srssim -n300 -R32 -s0 -S5 -y2 -z2 -d 19 -u 3) +add_physim_test(physim.5g.nr_srssim.test9 "SRS: 30KHz SCS, 106 PRBs, ToA 11, Combsize 4" nr_srssim -n300 -R106 -s5 -S10 -y2 -z2 -d 11 -e 1) +add_physim_test(physim.5g.nr_srssim.test10 "SRS: 30KHz SCS, 106 PRBs, ToA 7, Combsize 4, Comb offset 1" nr_srssim -n300 -R106 -s5 -S10 -y2 -z2 -d 7 -e 1 -f 1) +add_physim_test(physim.5g.nr_srssim.test11 "SRS: 30KHz SCS, 106 PRBs, ToA 24, Combsize 2, SRS symbols 2, SRS start symbol 8" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 24 -b 2 -a 8) +add_physim_test(physim.5g.nr_srssim.test12 "SRS: 30KHz SCS, 106 PRBs, ToA 24, Combsize 2, SRS symbols 4, SRS start symbol 8" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 24 -b 4 -a 8) +add_physim_test(physim.5g.nr_srssim.test13 "SRS: 30KHz SCS, 106 PRBs, ToA 24, Combsize 4, SRS symbols 2, SRS start symbol 8" nr_srssim -n300 -R106 -s5 -S10 -y2 -z2 -d 24 -b 2 -e1 -a 8) +add_physim_test(physim.5g.nr_srssim.test14 "SRS: 30KHz SCS, 106 PRBs, ToA 24, Combsize 4, SRS symbols 4, SRS start symbol 8" nr_srssim -n300 -R106 -s5 -S10 -y2 -z2 -d 24 -b 4 -e1 -a 8) +add_physim_test(physim.5g.nr_srssim.test15 "SRS: 30KHz SCS, 217 PRBs, ToA 8, Combsize 2, SRS symbols 4, SRS start symbol 8" nr_srssim -n300 -R217 -s0 -S5 -y2 -z2 -d 8 -b 4 -a 8) +add_physim_test(physim.5g.nr_srssim.test16 "SRS: 30KHz SCS, 106 PRBs, SNR 2 dB to 30 dB in steps of 5 dB, ToA 24, Combsize 2" nr_srssim -n300 -R106 -s2 -S30 -y2 -z2 -d 24) + #################################################################################### ###### offload-specific tests ###### #################################################################################### diff --git a/openair1/SIMULATION/tests/ThresholdsOffload.cmake b/openair1/SIMULATION/tests/ThresholdsOffload.cmake index 9f787f993a..a3cfcd738a 100644 --- a/openair1/SIMULATION/tests/ThresholdsOffload.cmake +++ b/openair1/SIMULATION/tests/ThresholdsOffload.cmake @@ -2,42 +2,42 @@ check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.1 "DLSCH encoding ti check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.1 "DLSCH encoding time" AVG 19 ABS_VAR 4) check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.2 "DLSCH encoding time" AVG 65 ABS_VAR 13) check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.2 "DLSCH encoding time" AVG 27 ABS_VAR 6) -check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.3 "DLSCH encoding time" AVG 97 ABS_VAR 20) -check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.3 "DLSCH encoding time" AVG 33 ABS_VAR 7) -check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.4 "DLSCH encoding time" AVG 68 ABS_VAR 14) -check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.4 "DLSCH encoding time" AVG 26 ABS_VAR 6) -check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.5 "DLSCH encoding time" AVG 108 ABS_VAR 22) -check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.5 "DLSCH encoding time" AVG 46 ABS_VAR 10) -check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.6 "DLSCH encoding time" AVG 131 ABS_VAR 27) -check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.6 "DLSCH encoding time" AVG 80 ABS_VAR 16) -check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.7 "DLSCH encoding time" AVG 120 ABS_VAR 24) -check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.7 "DLSCH encoding time" AVG 44 ABS_VAR 9) -check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.8 "DLSCH encoding time" AVG 146 ABS_VAR 30) -check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.8 "DLSCH encoding time" AVG 87 ABS_VAR 18) -check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.9 "DLSCH encoding time" AVG 204 ABS_VAR 41) -check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.9 "DLSCH encoding time" AVG 138 ABS_VAR 28) -check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.10 "DLSCH encoding time" AVG 149 ABS_VAR 30) -check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.10 "DLSCH encoding time" AVG 49 ABS_VAR 10) -check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.11 "DLSCH encoding time" AVG 164 ABS_VAR 33) -check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.11 "DLSCH encoding time" AVG 90 ABS_VAR 18) -check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.12 "DLSCH encoding time" AVG 223 ABS_VAR 45) -check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.12 "DLSCH encoding time" AVG 146 ABS_VAR 30) +check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.3 "DLSCH encoding time" AVG 98 ABS_VAR 20) +check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.3 "DLSCH encoding time" AVG 34 ABS_VAR 7) +check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.4 "DLSCH encoding time" AVG 66 ABS_VAR 14) +check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.4 "DLSCH encoding time" AVG 27 ABS_VAR 6) +check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.5 "DLSCH encoding time" AVG 109 ABS_VAR 22) +check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.5 "DLSCH encoding time" AVG 45 ABS_VAR 9) +check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.6 "DLSCH encoding time" AVG 127 ABS_VAR 26) +check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.6 "DLSCH encoding time" AVG 79 ABS_VAR 16) +check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.7 "DLSCH encoding time" AVG 109 ABS_VAR 33) +check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.7 "DLSCH encoding time" AVG 43 ABS_VAR 9) +check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.8 "DLSCH encoding time" AVG 141 ABS_VAR 29) +check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.8 "DLSCH encoding time" AVG 83 ABS_VAR 17) +check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.9 "DLSCH encoding time" AVG 196 ABS_VAR 40) +check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.9 "DLSCH encoding time" AVG 134 ABS_VAR 27) +check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.10 "DLSCH encoding time" AVG 132 ABS_VAR 27) +check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.10 "DLSCH encoding time" AVG 47 ABS_VAR 10) +check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.11 "DLSCH encoding time" AVG 158 ABS_VAR 32) +check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.11 "DLSCH encoding time" AVG 89 ABS_VAR 18) +check_threshold_variance(physim.5g-offload.nr_dlsim.testCPU.12 "DLSCH encoding time" AVG 214 ABS_VAR 43) +check_threshold_variance(physim.5g-offload.nr_dlsim.testT2.12 "DLSCH encoding time" AVG 144 ABS_VAR 29) check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.1 "ULSCH total decoding time" AVG 141 ABS_VAR 29) -check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.1 "ULSCH total decoding time" AVG 40 ABS_VAR 8) +check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.1 "ULSCH total decoding time" AVG 38 ABS_VAR 8) check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.2 "ULSCH total decoding time" AVG 165 ABS_VAR 33) -check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.2 "ULSCH total decoding time" AVG 63 ABS_VAR 13) -check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.3 "ULSCH total decoding time" AVG 156 ABS_VAR 32) -check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.3 "ULSCH total decoding time" AVG 87 ABS_VAR 18) -check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.4 "ULSCH total decoding time" AVG 170 ABS_VAR 34) -check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.4 "ULSCH total decoding time" AVG 74 ABS_VAR 15) -check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.5 "ULSCH total decoding time" AVG 299 ABS_VAR 60) -check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.5 "ULSCH total decoding time" AVG 120 ABS_VAR 24) -check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.6 "ULSCH total decoding time" AVG 324 ABS_VAR 65) -check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.6 "ULSCH total decoding time" AVG 180 ABS_VAR 36) +check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.2 "ULSCH total decoding time" AVG 57 ABS_VAR 12) +check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.3 "ULSCH total decoding time" AVG 155 ABS_VAR 31) +check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.3 "ULSCH total decoding time" AVG 80 ABS_VAR 16) +check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.4 "ULSCH total decoding time" AVG 169 ABS_VAR 34) +check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.4 "ULSCH total decoding time" AVG 68 ABS_VAR 14) +check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.5 "ULSCH total decoding time" AVG 298 ABS_VAR 60) +check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.5 "ULSCH total decoding time" AVG 115 ABS_VAR 23) +check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.6 "ULSCH total decoding time" AVG 321 ABS_VAR 65) +check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.6 "ULSCH total decoding time" AVG 162 ABS_VAR 33) check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.7 "ULSCH total decoding time" AVG 200 ABS_VAR 40) -check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.7 "ULSCH total decoding time" AVG 120 ABS_VAR 24) -check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.8 "ULSCH total decoding time" AVG 436 ABS_VAR 88) -check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.8 "ULSCH total decoding time" AVG 229 ABS_VAR 46) -check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.9 "ULSCH total decoding time" AVG 530 ABS_VAR 106) -check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.9 "ULSCH total decoding time" AVG 334 ABS_VAR 67) +check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.7 "ULSCH total decoding time" AVG 112 ABS_VAR 23) +check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.8 "ULSCH total decoding time" AVG 433 ABS_VAR 87) +check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.8 "ULSCH total decoding time" AVG 206 ABS_VAR 42) +check_threshold_variance(physim.5g-offload.nr_ulsim.testCPU.9 "ULSCH total decoding time" AVG 527 ABS_VAR 106) +check_threshold_variance(physim.5g-offload.nr_ulsim.testT2.9 "ULSCH total decoding time" AVG 302 ABS_VAR 61) diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index c5c18a12f2..a0314484eb 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -78,6 +78,7 @@ typedef struct NRRrcMacRaInd_s { bool RA_succeeded; + int gnb_index; } NRRrcMacRaInd; typedef struct NRRrcMacMsg3Ind_s { @@ -121,6 +122,7 @@ typedef struct RrcMacBcchDataInd_s { } RrcMacBcchDataInd; typedef struct NRRrcMacBcchDataInd_s { + uint32_t hfn; uint32_t frame; uint8_t slot; uint32_t sdu_size; @@ -134,6 +136,7 @@ typedef struct NRRrcMacBcchDataInd_s { } NRRrcMacBcchDataInd; typedef struct NRRrcMacSBcchDataInd_s { + uint32_t hfn; uint32_t frame; uint8_t slot; uint32_t sdu_size; diff --git a/openair2/COMMON/ngap_messages_def.h b/openair2/COMMON/ngap_messages_def.h index 98c1f82260..26f607f884 100644 --- a/openair2/COMMON/ngap_messages_def.h +++ b/openair2/COMMON/ngap_messages_def.h @@ -64,7 +64,6 @@ MESSAGE_DEF(NGAP_UE_CAPABILITIES_IND , MESSAGE_PRIORITY_MED, ngap_ue_cap_i MESSAGE_DEF(NGAP_INITIAL_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, ngap_initial_context_setup_resp_t, ngap_initial_context_setup_resp) MESSAGE_DEF(NGAP_INITIAL_CONTEXT_SETUP_FAIL, MESSAGE_PRIORITY_MED, ngap_initial_context_setup_fail_t, ngap_initial_context_setup_fail) MESSAGE_DEF(NGAP_NAS_NON_DELIVERY_IND , MESSAGE_PRIORITY_MED, ngap_nas_non_delivery_ind_t , ngap_nas_non_delivery_ind) -MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_RESP , MESSAGE_PRIORITY_MED, ngap_ue_release_resp_t , ngap_ue_release_resp) MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, ngap_ue_release_complete_t , ngap_ue_release_complete) MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_RESP , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_resp_t , ngap_ue_ctxt_modification_resp) MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_FAIL , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_fail_t , ngap_ue_ctxt_modification_fail) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 5be5e316ef..0aad7b8598 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -47,7 +47,6 @@ #define NGAP_UE_CAPABILITIES_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_cap_info_ind #define NGAP_INITIAL_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_initial_context_setup_resp #define NGAP_INITIAL_CONTEXT_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_initial_context_setup_fail -#define NGAP_UE_CONTEXT_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_resp #define NGAP_NAS_NON_DELIVERY_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_nas_non_delivery_ind #define NGAP_UE_CTXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_resp #define NGAP_UE_CTXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_fail @@ -474,8 +473,8 @@ typedef struct { cell_id_t id; // Cell type uint8_t type; - // Time UE Stayed in Cell - long time_in_cell; + // Time UE Stayed in Cell (seconds) + uint16_t time_in_cell; // Cause ngap_cause_t *cause; } last_visited_ngran_cell_info_t; @@ -733,17 +732,13 @@ typedef struct ngap_ue_ctxt_modification_resp_s { uint32_t gNB_ue_ngap_id; } ngap_ue_ctxt_modification_resp_t; -typedef struct ngap_ue_release_complete_s { - uint32_t gNB_ue_ngap_id; - int num_pdu_sessions; - uint32_t pdu_session_id[256]; -} ngap_ue_release_complete_t; - //-------------------------------------------------------------------------------------------// // NGAP -> RRC messages typedef struct ngap_downlink_nas_s { /* UE id for initial connection to NGAP */ uint32_t gNB_ue_ngap_id; + /* UE id at AMF */ + uint64_t amf_ue_ngap_id; /* NAS pdu */ byte_array_t nas_pdu; } ngap_downlink_nas_t; @@ -862,20 +857,24 @@ typedef struct ngap_ue_release_command_s { //-------------------------------------------------------------------------------------------// // NGAP <-- RRC messages -typedef struct pdusession_release_s { - /* Unique pdusession_id for the UE. */ - uint8_t pdusession_id; - byte_array_t data; -} pdusession_release_t; - typedef struct ngap_ue_release_req_s { - uint32_t gNB_ue_ngap_id; - /* Number of pdusession resource in the list */ + // RAN UE NGAP ID (mandatory) + uint32_t gNB_ue_ngap_id; + // PDU Session Resource List (optional) uint16_t nb_of_pdusessions; - /* list of pdusession resource by RRC layers */ - pdusession_release_t pdusessions[NGAP_MAX_PDU_SESSION]; + uint8_t pdusession_ids[NGAP_MAX_PDU_SESSION]; + // Cause (mandatory) ngap_cause_t cause; -} ngap_ue_release_req_t, ngap_ue_release_resp_t; +} ngap_ue_release_req_t; + +typedef struct { + // RAN UE NGAP ID (mandatory) + uint32_t gNB_ue_ngap_id; + // PDU Session Resource List (optional) + uint16_t num_pdu_sessions; + // PDU Session ID (mandatory) + uint8_t pdu_session_id[NGAP_MAX_PDU_SESSION]; +} ngap_ue_release_complete_t; typedef struct ngap_pdusession_modify_req_s { /* AMF UE id */ @@ -915,14 +914,19 @@ typedef struct ngap_pdusession_release_command_s { /* The NAS PDU should be forwarded by the RRC layer to the NAS layer */ byte_array_t nas_pdu; - /* Number of pdusession to be released in the list */ + // PDU Session Resource to Release List (mandatory) uint16_t nb_pdusessions_torelease; - - /* PDUSession release command */ - pdusession_release_t pdusession_release_params[NGAP_MAX_PDU_SESSION]; + uint16_t pdusession_ids[NGAP_MAX_PDU_SESSION]; } ngap_pdusession_release_command_t; +typedef struct pdusession_release_s { + // PDU Session ID (mandatory) + uint8_t pdusession_id; + // PDU Session Resource Release Response Transfer (mandatory) + byte_array_t pdusession_release_response_transfer; +} pdusession_release_t; + typedef struct ngap_pdusession_release_resp_s { // AMF UE NGAP ID uint64_t amf_ue_ngap_id; diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 255da9f189..cfc6914f4b 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -438,6 +438,7 @@ typedef struct rrc_subframe_process_s { } RrcSubframeProcess; typedef struct nrrrc_frame_process_s { + int hfn; int frame; int gnb_id; } NRRrcFrameProcess; @@ -475,10 +476,11 @@ typedef struct { typedef struct { NR_CellGroupConfig_t *cellGroupConfig; NR_UE_NR_Capability_t *UE_NR_Capability; + int hfn; + int frame; } nr_mac_rrc_config_cg_t; typedef struct { NR_BCCH_BCH_Message_t *bcch; - int get_sib; bool access_barred; } nr_mac_rrc_config_mib_t; typedef struct { @@ -487,8 +489,14 @@ typedef struct { } nr_mac_rrc_config_sib1_t; typedef struct { NR_SIB19_r17_t *sib19; + int hfn; + int frame; bool can_start_ra; } nr_mac_rrc_config_other_sib_t; +typedef struct { + int get_sib; +} nr_mac_rrc_sched_sib_t; + enum payload_type { NR_MAC_RRC_CONFIG_RESET, @@ -496,6 +504,7 @@ enum payload_type { NR_MAC_RRC_CONFIG_MIB, NR_MAC_RRC_CONFIG_SIB1, NR_MAC_RRC_CONFIG_OTHER_SIB, + NR_MAC_RRC_SCHED_SIB, NR_MAC_RRC_RESUME_RB }; @@ -506,6 +515,7 @@ typedef struct { nr_mac_rrc_config_cg_t config_cg; nr_mac_rrc_config_mib_t config_mib; nr_mac_rrc_config_sib1_t config_sib1; + nr_mac_rrc_sched_sib_t sched_sib; nr_mac_rrc_config_other_sib_t config_other_sib; nr_mac_rrc_resume_rb_t resume_rb; } payload; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 081ce8607f..36ee2e4f0c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -699,7 +699,6 @@ void RCconfig_verify(configmodule_interface_t *cfg, ngran_node_t node_type) verify_gnb_param_notset(gnbp, GNB_PDSCH_ANTENNAPORTS_XP_IDX, GNB_CONFIG_STRING_PDSCHANTENNAPORTS_XP); verify_gnb_param_notset(gnbp, GNB_PUSCH_ANTENNAPORTS_IDX, GNB_CONFIG_STRING_PUSCHANTENNAPORTS); verify_gnb_param_notset(gnbp, GNB_MINRXTXTIME_IDX, GNB_CONFIG_STRING_MINRXTXTIME); - verify_gnb_param_notset(gnbp, GNB_SIB1_TDA_IDX, GNB_CONFIG_STRING_SIB1TDA); verify_gnb_param_notset(gnbp, GNB_DO_CSIRS_IDX, GNB_CONFIG_STRING_DOCSIRS); verify_gnb_param_notset(gnbp, GNB_DO_SRS_IDX, GNB_CONFIG_STRING_DOSRS); verify_gnb_param_notset(gnbp, GNB_FORCE256QAMOFF_IDX, GNB_CONFIG_STRING_FORCE256QAMOFF); @@ -1368,7 +1367,7 @@ void nfapi_stop_l1() } } -static void get_bwp_config(nr_mac_config_t *configuration) +static void get_bwp_config(nr_mac_config_t *configuration, const NR_ServingCellConfigCommon_t *scc) { char path[MAX_OPTNAME_SIZE * 2 + 8]; snprintf(path, sizeof(path), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); @@ -1377,10 +1376,13 @@ static void get_bwp_config(nr_mac_config_t *configuration) AssertFatal(configuration->num_additional_bwps >= 0 && configuration->num_additional_bwps <= 4, "Invalid number of additional BWPs %d\n", configuration->num_additional_bwps); + int bw = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; for (int i = 0; i < configuration->num_additional_bwps; i++) { configuration->bwp_config[i].id = i + 1; int bwp_start = *BWPParamList.paramarray[i][GNB_BWP_START_IDX].iptr; + AssertFatal(bwp_start >= 0 && bwp_start < bw, "Invalid BWP start value %d\n", bwp_start); int bwp_size = *BWPParamList.paramarray[i][GNB_BWP_SIZE_IDX].iptr; + AssertFatal(bwp_start + bwp_size <= bw, "BWP start %d and BWP size %d exceeds full BW %d\n", bwp_start, bwp_size, bw); configuration->bwp_config[i].location_and_bw = PRBalloc_to_locationandbandwidth(bwp_size, bwp_start); configuration->bwp_config[i].scs = *BWPParamList.paramarray[i][GNB_BWP_SCS_IDX].iptr; LOG_I(GNB_APP, @@ -1418,12 +1420,6 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) config.pdsch_AntennaPorts.XP, config.pusch_AntennaPorts); - // BWP - get_bwp_config(&config); - AssertFatal(config.num_additional_bwps <= 4, "Impossible to configure more than 4 additional BWPs\n"); - config.first_active_bwp = *GNBParamList.paramarray[0][GNB_1ST_ACTIVE_BWP_IDX].iptr; - AssertFatal(config.first_active_bwp <= config.num_additional_bwps, "1st active BWP does not belog to the configured BWPs\n"); - // RU GET_PARAMS_LIST(RUParamList, RUParams, RUPARAMS_DESC, CONFIG_STRING_RU_LIST, NULL); int num_tx = 0; @@ -1439,8 +1435,6 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) } config.minRXTXTIME = *GNBParamList.paramarray[0][GNB_MINRXTXTIME_IDX].iptr; LOG_I(GNB_APP, "minTXRXTIME %d\n", config.minRXTXTIME); - config.sib1_tda = *GNBParamList.paramarray[0][GNB_SIB1_TDA_IDX].iptr; - LOG_I(GNB_APP, "SIB1 TDA %d\n", config.sib1_tda); config.do_CSIRS = *GNBParamList.paramarray[0][GNB_DO_CSIRS_IDX].iptr; config.do_SRS = *GNBParamList.paramarray[0][GNB_DO_SRS_IDX].iptr; config.max_num_rsrp = *GNBParamList.paramarray[0][GNB_LIMIT_RSRP_REPORT_IDX].iptr; @@ -1524,7 +1518,11 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) config.num_agg_level_candidates[PDCCH_AGG_LEVEL16]); NR_ServingCellConfigCommon_t *scc = get_scc_config(cfg, config.minRXTXTIME, config.do_SRS); - //xer_fprint(stdout, &asn_DEF_NR_ServingCellConfigCommon, scc); + // BWP + get_bwp_config(&config, scc); + AssertFatal(config.num_additional_bwps <= 4, "Impossible to configure more than 4 additional BWPs\n"); + config.first_active_bwp = *GNBParamList.paramarray[0][GNB_1ST_ACTIVE_BWP_IDX].iptr; + AssertFatal(config.first_active_bwp <= config.num_additional_bwps, "1st active BWP does not belog to the configured BWPs\n"); if (MacRLC_ParamList.numelt > 0) { /* NR RLC config is needed by mac_top_init_gNB() */ @@ -1629,10 +1627,11 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) AssertFatal(NFAPI_MODE == NFAPI_MONOLITHIC, "Analog beamforming only supported for monolithic scenario\n"); NR_beam_info_t *beam_info = &RC.nrmac[j]->beam_info; int beams_per_period = *MacRLC_ParamList.paramarray[j][MACRLC_ANALOG_BEAMS_PERIOD_IDX].u8ptr; - beam_info->beam_allocation = malloc16(beams_per_period * sizeof(int *)); + beam_info->beam_allocation = malloc16(beams_per_period * sizeof(beam_info->beam_allocation)); beam_info->beam_duration = *MacRLC_ParamList.paramarray[j][MACRLC_ANALOG_BEAM_DURATION_IDX].u8ptr; beam_info->beams_per_period = beams_per_period; beam_info->beam_allocation_size = -1; // to be initialized once we have information on frame configuration + // TODO: Indicate this to MAC via FAPI TLV 0x0164. beam_info->beam_mode = ab == 1 ? PRECONFIGURED_BEAM_IDX : LOPHY_BEAM_IDX; } else { RC.nrmac[j]->beam_info.beam_mode = NO_BEAM_MODE; diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 4ec09d06f0..14cd6ba3c8 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -114,7 +114,6 @@ typedef enum { #define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N2 "pdsch_AntennaPorts_N2" #define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_XP "pdsch_AntennaPorts_XP" #define GNB_CONFIG_STRING_PUSCHANTENNAPORTS "pusch_AntennaPorts" -#define GNB_CONFIG_STRING_SIB1TDA "sib1_tda" #define GNB_CONFIG_STRING_DOCSIRS "do_CSIRS" #define GNB_CONFIG_STRING_DOSRS "do_SRS" #define GNB_CONFIG_STRING_NRCELLID "nr_cellid" @@ -179,7 +178,6 @@ typedef enum { {GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N2, "vert. log. antenna ports", 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PDSCHANTENNAPORTS_XP, "XP log. antenna ports", 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PUSCHANTENNAPORTS, NULL, 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \ -{GNB_CONFIG_STRING_SIB1TDA, NULL, 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_DOCSIRS, NULL, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_DOSRS, NULL, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_NRCELLID, NULL, 0, .u64ptr=NULL,.defint64val=1, TYPE_UINT64, 0}, \ @@ -225,30 +223,29 @@ typedef enum { #define GNB_PDSCH_ANTENNAPORTS_N2_IDX 14 #define GNB_PDSCH_ANTENNAPORTS_XP_IDX 15 #define GNB_PUSCH_ANTENNAPORTS_IDX 16 -#define GNB_SIB1_TDA_IDX 17 -#define GNB_DO_CSIRS_IDX 18 -#define GNB_DO_SRS_IDX 19 -#define GNB_NRCELLID_IDX 20 -#define GNB_MINRXTXTIME_IDX 21 -#define GNB_ULPRBBLACKLIST_IDX 22 -#define GNB_UMONDEFAULTDRB_IDX 23 -#define GNB_FORCE256QAMOFF_IDX 24 -#define GNB_ENABLE_SDAP_IDX 25 -#define GNB_DRBS 26 -#define GNB_GNB_DU_ID_IDX 27 -#define GNB_GNB_CU_UP_ID_IDX 28 -#define GNB_USE_DELTA_MCS_IDX 29 -#define GNB_FORCEUL256QAMOFF_IDX 30 -#define GNB_MAXMIMOLAYERS_IDX 31 -#define GNB_DISABLE_HARQ_IDX 32 -#define GNB_NUM_DL_HARQ_IDX 33 -#define GNB_NUM_UL_HARQ_IDX 34 -#define GNB_UESS_AGG_LEVEL_LIST_IDX 35 -#define GNB_CU_SIBS_IDX 36 -#define GNB_DU_SIBS_IDX 37 -#define GNB_CONFIG_REP_IDX 38 -#define GNB_1ST_ACTIVE_BWP_IDX 39 -#define GNB_LIMIT_RSRP_REPORT_IDX 40 +#define GNB_DO_CSIRS_IDX 17 +#define GNB_DO_SRS_IDX 18 +#define GNB_NRCELLID_IDX 19 +#define GNB_MINRXTXTIME_IDX 20 +#define GNB_ULPRBBLACKLIST_IDX 21 +#define GNB_UMONDEFAULTDRB_IDX 22 +#define GNB_FORCE256QAMOFF_IDX 23 +#define GNB_ENABLE_SDAP_IDX 24 +#define GNB_DRBS 25 +#define GNB_GNB_DU_ID_IDX 26 +#define GNB_GNB_CU_UP_ID_IDX 27 +#define GNB_USE_DELTA_MCS_IDX 28 +#define GNB_FORCEUL256QAMOFF_IDX 29 +#define GNB_MAXMIMOLAYERS_IDX 30 +#define GNB_DISABLE_HARQ_IDX 31 +#define GNB_NUM_DL_HARQ_IDX 32 +#define GNB_NUM_UL_HARQ_IDX 33 +#define GNB_UESS_AGG_LEVEL_LIST_IDX 34 +#define GNB_CU_SIBS_IDX 35 +#define GNB_DU_SIBS_IDX 36 +#define GNB_CONFIG_REP_IDX 37 +#define GNB_1ST_ACTIVE_BWP_IDX 38 +#define GNB_LIMIT_RSRP_REPORT_IDX 39 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define NUM_DL_HARQ_OKVALUES {2,4,6,8,10,12,16,32} @@ -287,7 +284,6 @@ typedef enum { { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ - { .s5 = { NULL } }, \ { .s1 = { config_check_intval, NUM_DL_HARQ_OKVALUES,8 } }, \ { .s1 = { config_check_intval, NUM_UL_HARQ_OKVALUES,2 } }, \ { .s5 = { NULL } }, \ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 13f2eca955..563b3f2ca2 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2781,7 +2781,6 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, nr_dci_format_t format, nr_rnti_type_t rnti_type, NR_ControlResourceSet_t *coreset, - int bwp_id, int ss_type, uint16_t cset0_bwp_size, uint16_t alt_size) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index f76f54b158..8f795452b8 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -159,7 +159,6 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP, nr_dci_format_t format, nr_rnti_type_t rnti_type, NR_ControlResourceSet_t *coreset, - int bwp_id, int ss_type, uint16_t cset0_bwp_size, uint16_t alt_size); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_prach_config.h b/openair2/LAYER2/NR_MAC_COMMON/nr_prach_config.h index 1b6aa0bfb7..5898e2b80c 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_prach_config.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_prach_config.h @@ -30,6 +30,9 @@ * For example the PRACH duration is requested in the O-RAN 7.2 FrontHaul Interface */ +#ifndef __NR_PRACH_CONFIG_H__ +#define __NR_PRACH_CONFIG_H__ + /** * @brief Fetch PRACH format (format only) from PRACH configuration tables * @@ -73,3 +76,5 @@ nr_prach_info_t get_nr_prach_occasion_info_from_index(uint8_t index, frequency_r * @return PRACH format (format concatenated with format2) */ uint16_t get_nr_prach_format_from_index(uint8_t index, uint32_t pointa, uint8_t unpaired); + +#endif diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index f592423c5a..3185d040ed 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -31,7 +31,6 @@ */ #define _GNU_SOURCE -#define SPEED_OF_LIGHT 299792458 #include "mac_defs.h" #include "NR_MAC_UE/mac_proto.h" @@ -41,7 +40,6 @@ #include "executables/softmodem-common.h" #include "SCHED_NR/phy_frame_config_nr.h" #include "oai_asn1.h" -#include "executables/position_interface.h" #define ASIGN_P_VAL(dst, src) \ do { \ @@ -144,9 +142,21 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); - uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) * - (15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); - cfg->carrier_config.dl_frequency = (downlink_frequency[cc_idP][0]/1000) - (dl_bw_khz>>1); + /** Only set frequency if not already initialized (e.g., from handover reconfigurationWithSync) + * MAC maintains its own frequency state, don't overwrite it with command-line parameter which + * is related to the initial cell selection. */ + if (cfg->carrier_config.dl_frequency == 0) { + // Initial cell selection: derive from command-line parameter + uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) * + (15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); + cfg->carrier_config.dl_frequency = (downlink_frequency[cc_idP][0]/1000) - (dl_bw_khz>>1); + LOG_I(NR_MAC, + "[UE %d] Initial cell selection: dl_frequency=%u kHz (from command-line, band=%d, scs=%ld)\n", + mac->ue_id, + cfg->carrier_config.dl_frequency, + mac->nr_band, + frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); + } for (int i = 0; i < 5; i++) { if (i == frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) { @@ -167,10 +177,21 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); - if (frequencyInfoUL->absoluteFrequencyPointA == NULL) - cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency; - else - cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency + (uplink_frequency_offset[cc_idP][0] / 1000); + /** Only set UL frequency if not already initialized (e.g., from handover reconfigurationWithSync) + * MAC maintains its own frequency state, don't overwrite it with command-line parameter which + * is related to the initial cell selection. */ + if (cfg->carrier_config.uplink_frequency == 0) { + // Initial cell selection: derive from DL frequency + LOG_I(NR_MAC, + "Initial cell selection: uplink_frequency=%u kHz (from dl_frequency=%u kHz, uplink_frequency_offset=%u kHz)\n", + cfg->carrier_config.uplink_frequency, + cfg->carrier_config.dl_frequency, + uplink_frequency_offset[cc_idP][0]); + if (frequencyInfoUL->absoluteFrequencyPointA == NULL) + cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency; + else + cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency + (uplink_frequency_offset[cc_idP][0] / 1000); + } for (int i = 0; i < 5; i++) { if (i == frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) { @@ -262,82 +283,92 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo mac->frequency_range); //prach_fd_occasion->num_unused_root_sequences = ??? } - cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1; - } -// computes round-trip-time between ue and sat based on SIB19 ephemeris data -static void calculate_ue_sat_ta(const position_t *position_params, - const NR_PositionVelocity_r17_t *sat_pos, - ntn_timing_advance_componets_t *ntn_ta) +// prepare data for orbit propagation based on SIB19 ephemeris data to be able to compute the round-trip-time between ue and sat +static void prepare_ue_sat_ta(const NR_PositionVelocity_r17_t *sat_pos, fapi_nr_ntn_config_t *ntn_ta) { - // get UE position coordinates - const position_t pos_ue = *position_params; - // get sat position coordinates const position_t pos_sat = {sat_pos->positionX_r17 * 1.3, sat_pos->positionY_r17 * 1.3, sat_pos->positionZ_r17 * 1.3}; - // calculate directional vector from SAT to UE - const position_t dir_sat_ue = {pos_ue.X - pos_sat.X, pos_ue.Y - pos_sat.Y, pos_ue.Z - pos_sat.Z}; - - // calculate distance between SAT and UE - double distance = sqrt(dir_sat_ue.X * dir_sat_ue.X + dir_sat_ue.Y * dir_sat_ue.Y + dir_sat_ue.Z * dir_sat_ue.Z); - // get sat velocity vector const position_t vel_sat = {sat_pos->velocityVX_r17 * 0.06, sat_pos->velocityVY_r17 * 0.06, sat_pos->velocityVZ_r17 * 0.06}; - // calculate SAT velocity towards UE - double velocity = (vel_sat.X * dir_sat_ue.X + vel_sat.Y * dir_sat_ue.Y + vel_sat.Z * dir_sat_ue.Z) / distance; - - // calculate SAT acceleration towards UE + // calculate orbital radius const double radius_2 = pos_sat.X * pos_sat.X + pos_sat.Y * pos_sat.Y + pos_sat.Z * pos_sat.Z; + const double radius = sqrt(radius_2); + + // calculate sat velocity magnitude const double vel_sat_2 = vel_sat.X * vel_sat.X + vel_sat.Y * vel_sat.Y + vel_sat.Z * vel_sat.Z; - const double acceleration = - -(pos_sat.X * dir_sat_ue.X + pos_sat.Y * dir_sat_ue.Y + pos_sat.Z * dir_sat_ue.Z) * vel_sat_2 / (radius_2 * distance); + const double vel_mag = sqrt(vel_sat_2); - LOG_D(NR_MAC, "Satellite velocity towards UE: %f m/s, acceleration towards UE: %f m/s²\n", velocity, acceleration); + double omega; // angular velocity in rad/ms + position_t pos_sat_90; // sat position vector in 90° orbit + position_t vel_sat_90; // sat velocity vector in 90° orbit - ntn_ta->N_UE_TA_adj = (2 * distance / SPEED_OF_LIGHT) * 1e3; // in ms - ntn_ta->N_UE_TA_drift = (2 * -velocity / SPEED_OF_LIGHT) * 1e6; // in µs/s - ntn_ta->N_UE_TA_drift_variant = (2 * acceleration / SPEED_OF_LIGHT) * 1e6; // in µs/s² + // assuming circular orbit when satellite moves faster than 1000 m/s + // 1000 m/s are chosen because according to Wikipedia, this seems to be a reasonable minimal + // orbital velocity: https://en.wikipedia.org/wiki/Orbital_speed#Tangential_velocities_at_altitude + if (vel_mag > 1000) { + omega = vel_mag / (radius * 1000); + double scaling = radius / vel_mag; + pos_sat_90 = (position_t){vel_sat.X * scaling, vel_sat.Y * scaling, vel_sat.Z * scaling}; + scaling = -vel_mag / radius; + vel_sat_90 = (position_t){pos_sat.X * scaling, pos_sat.Y * scaling, pos_sat.Z * scaling}; + } else { + omega = 0; + pos_sat_90 = pos_sat; + vel_sat_90 = vel_sat; + } + + LOG_I(NR_MAC, + "Satellite orbital radius %f m, pos_sat_0 = {%f, %f, %f}, pos_sat_90 = {%f, %f, %f}\n", + radius, + pos_sat.X, + pos_sat.Y, + pos_sat.Z, + pos_sat_90.X, + pos_sat_90.Y, + pos_sat_90.Z); + + LOG_I(NR_MAC, + "Satellite velocity %f m/s, angular velocity = %e rad/ms, vel_sat_0 = {%f, %f, %f}, vel_sat_90 = {%f, %f, %f}\n", + vel_mag, + omega, + vel_sat.X, + vel_sat.Y, + vel_sat.Z, + vel_sat_90.X, + vel_sat_90.Y, + vel_sat_90.Z); + + ntn_ta->omega = omega; + ntn_ta->pos_sat_0 = pos_sat; + ntn_ta->pos_sat_90 = pos_sat_90; + ntn_ta->vel_sat_0 = vel_sat; + ntn_ta->vel_sat_90 = vel_sat_90; } // populate ntn_ta structure from mac -static void configure_ntn_ta(module_id_t module_id, - ntn_timing_advance_componets_t *ntn_ta, - const NR_NTN_Config_r17_t *ntn_Config_r17) +static void configure_ntn_ta(fapi_nr_ntn_config_t *ntn_ta, + const NR_NTN_Config_r17_t *ntn_Config_r17, + int hfn, + int frame, + bool is_targetcell) { if (!ntn_Config_r17) return; - position_t position_params = {0}; - get_position_coordinates(module_id, &position_params); - // epochTime_r17 must be present (this is assured by function `eval_epoch_time()`) const NR_EpochTime_r17_t *epoch_time_r17 = ntn_Config_r17->epochTime_r17; AssertFatal(epoch_time_r17, "epoch_time_r17 should not be NULL here\n"); + if (epoch_time_r17->sfn_r17 >= frame) + ntn_ta->epoch_hfn = hfn; + else + ntn_ta->epoch_hfn = hfn + 1; ntn_ta->epoch_sfn = epoch_time_r17->sfn_r17; ntn_ta->epoch_subframe = epoch_time_r17->subFrameNR_r17; - // handle ephemerisInfo_r17 - const NR_EphemerisInfo_r17_t *ephemeris_info = ntn_Config_r17->ephemerisInfo_r17; - if (ephemeris_info) { - if (ephemeris_info->present == NR_EphemerisInfo_r17_PR_positionVelocity_r17) { - const NR_PositionVelocity_r17_t *position_velocity = ephemeris_info->choice.positionVelocity_r17; - AssertFatal(position_velocity, "position_velocity should not be NULL here\n"); - calculate_ue_sat_ta(&position_params, position_velocity, ntn_ta); - } else { - LOG_W(NR_MAC, "NR UE currently supports only ephemerisInfo_r17 of type positionVelocity_r17\n"); - ntn_ta->N_UE_TA_adj = 0; - ntn_ta->N_UE_TA_drift = 0; - ntn_ta->N_UE_TA_drift_variant = 0; - } - } else { // Need R - Release if not present - ntn_ta->N_UE_TA_adj = 0; - ntn_ta->N_UE_TA_drift = 0; - ntn_ta->N_UE_TA_drift_variant = 0; - } - // handle cellSpecificKoffset_r17 if (ntn_Config_r17->cellSpecificKoffset_r17) ntn_ta->cell_specific_k_offset = *ntn_Config_r17->cellSpecificKoffset_r17; @@ -364,23 +395,45 @@ static void configure_ntn_ta(module_id_t module_id, ntn_ta->N_common_ta_drift_variant = 0; } - ntn_ta->ntn_params_changed = true; - - LOG_D(NR_MAC, - "SIB19 Rxd. Epoch SFN: %d, Epoch Subframe: %d, k_offset: %ldms, N_Common_Ta: %fms, drift: %fµs/s, variant %fµs/s², " - "N_UE_TA: %fms, drift: %fµs/s, variant %fµs/s²\n", + LOG_I(NR_MAC, + "NTN Config Rxd. Epoch HFN: %d, Epoch SFN: %d, Epoch Subframe: %d, k_offset: %ldms, " + "N_Common_Ta: %fms, drift: %fµs/s, variant: %fµs/s²\n", + ntn_ta->epoch_hfn, ntn_ta->epoch_sfn, ntn_ta->epoch_subframe, ntn_ta->cell_specific_k_offset, ntn_ta->N_common_ta_adj, ntn_ta->N_common_ta_drift, - ntn_ta->N_common_ta_drift_variant, - ntn_ta->N_UE_TA_adj, - ntn_ta->N_UE_TA_drift, - ntn_ta->N_UE_TA_drift_variant); + ntn_ta->N_common_ta_drift_variant); + + // handle ephemerisInfo_r17 + const NR_EphemerisInfo_r17_t *ephemeris_info = ntn_Config_r17->ephemerisInfo_r17; + if (ephemeris_info) { + if (ephemeris_info->present == NR_EphemerisInfo_r17_PR_positionVelocity_r17) { + const NR_PositionVelocity_r17_t *position_velocity = ephemeris_info->choice.positionVelocity_r17; + AssertFatal(position_velocity, "position_velocity should not be NULL here\n"); + prepare_ue_sat_ta(position_velocity, ntn_ta); + } else { + LOG_W(NR_MAC, "NR UE currently supports only ephemerisInfo_r17 of type positionVelocity_r17\n"); + ntn_ta->omega = 0; + ntn_ta->pos_sat_0 = (position_t){0, 0, 0}; + ntn_ta->pos_sat_90 = (position_t){0, 0, 0}; + ntn_ta->vel_sat_0 = (position_t){0, 0, 0}; + ntn_ta->vel_sat_90 = (position_t){0, 0, 0}; + } + } else { // Need R - Release if not present + ntn_ta->omega = 0; + ntn_ta->pos_sat_0 = (position_t){0, 0, 0}; + ntn_ta->pos_sat_90 = (position_t){0, 0, 0}; + ntn_ta->vel_sat_0 = (position_t){0, 0, 0}; + ntn_ta->vel_sat_90 = (position_t){0, 0, 0}; + } + + ntn_ta->is_targetcell = is_targetcell; + ntn_ta->params_changed = true; } -static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t *scc, int cc_idP) +static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t *scc, int cc_idP, int hfn, int frame) { fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; @@ -407,6 +460,13 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t *scc->ssbSubcarrierSpacing, frequencyInfoDL->absoluteFrequencyPointA) / 1000; // freq in kHz + LOG_I(NR_MAC, + "[UE %d] Set dl_frequency=%u kHz (from absoluteFrequencyPointA=%ld, band=%d, scs=%ld)\n", + mac->ue_id, + cfg->carrier_config.dl_frequency, + frequencyInfoDL->absoluteFrequencyPointA, + mac->nr_band, + *scc->ssbSubcarrierSpacing); for (int i = 0; i < 5; i++) { if (i == frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) { @@ -547,7 +607,6 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t prach_fd_occasion->num_root_sequences = compute_nr_root_seq(rach_ConfigCommon, nb_preambles, frame_type, mac->frequency_range); - cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present - 1; // prach_fd_occasion->num_unused_root_sequences = ??? } } @@ -555,7 +614,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t // NTN Config if (scc->ext2) { UPDATE_IE(mac->sc_info.ntn_Config_r17, scc->ext2->ntn_Config_r17, NR_NTN_Config_r17_t); - configure_ntn_ta(mac->ue_id, &mac->ntn_ta, mac->sc_info.ntn_Config_r17); + configure_ntn_ta(&mac->phy_config.config_req.ntn_config, mac->sc_info.ntn_Config_r17, hfn, frame, true); } else { asn1cFreeStruc(asn_DEF_NR_NTN_Config_r17, mac->sc_info.ntn_Config_r17); } @@ -886,7 +945,8 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac, nr_lcid_rb_t rb) { NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lc_info->lcid); - lc_info->rb = rb; + if (rb.type != NR_LCID_NONE) + lc_info->rb = rb; lc_info->rb_suspended = false; if (rb.type == NR_LCID_SRB && !mac_lc_config->ul_SpecificParameters) { // release configuration and reset to default @@ -914,6 +974,12 @@ static void nr_configure_lc_config(NR_UE_MAC_INST_t *mac, static nr_lcid_rb_t configure_lcid_rb(NR_RLC_BearerConfig_t *rlc_bearer) { nr_lcid_rb_t rb; + if (!rlc_bearer->servedRadioBearer) { + LOG_W(NR_MAC, "RLC bearer config does not contain servedRadioBearer.\n"); + rb.type = NR_LCID_NONE; + return rb; + } + if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { rb.type = NR_LCID_SRB; rb.choice.srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; @@ -953,8 +1019,6 @@ static void configure_logicalChannelBearer(NR_UE_MAC_INST_t *mac, for (int i = 0; i < rlc_toadd_list->list.count; i++) { NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i]; nr_lcid_rb_t rb = configure_lcid_rb(rlc_bearer); - if (rb.type == NR_LCID_NONE) - continue; int lc_identity = rlc_bearer->logicalChannelIdentity; NR_LogicalChannelConfig_t *mac_lc_config = rlc_bearer->mac_LogicalChannelConfig; int j; @@ -1022,7 +1086,21 @@ static bool is_cset0_present(frequency_range_t const fr, uint8_t const kssb) return (fr == FR1) ? (kssb < 24) : (kssb < 12); } -void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, int sched_sib, bool barred) +void nr_rrc_mac_sched_sib(module_id_t module_id, int sched_sib) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + if (sched_sib == 1) { + bool const is_c0 = is_cset0_present(mac->frequency_range, mac->ssb_subcarrier_offset); + mac->get_sib1 = is_c0; + AssertFatal(is_c0, "RRC scheduling SIB1 reception but MIB indicates no SIB1 present in current cell\n"); + } else if (sched_sib > 1) + mac->get_otherSI[sched_sib - 2] = true; + + if (mac->state == UE_NOT_SYNC && mac->get_sib1) + mac->state = UE_RECEIVING_SIB; +} + +void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, bool barred) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); int ret = pthread_mutex_lock(&mac->if_mutex); @@ -1042,22 +1120,10 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mib, mac->phy_config.CC_id = cc_idP; nr_ue_decode_mib(mac, cc_idP); - - if (sched_sib == 1) { - bool const is_c0 = is_cset0_present(mac->frequency_range, mac->ssb_subcarrier_offset); - mac->get_sib1 = is_c0; - AssertFatal(is_c0, "RRC scheduling SIB1 reception but MIB indicates no SIB1 present in current cell\n"); - } else if (sched_sib > 1) - mac->get_otherSI[sched_sib - 2] = true; - if (get_softmodem_params()->phy_test) mac->state = UE_CONNECTED; - else if (mac->state == UE_NOT_SYNC) { - if (IS_SA_MODE(get_softmodem_params()) && mac->get_sib1) - mac->state = UE_RECEIVING_SIB; - else - mac->state = UE_PERFORMING_RA; - } + else if (mac->state == UE_NOT_SYNC_RECONF) + mac->state = UE_PERFORMING_RA; ret = pthread_mutex_unlock(&mac->if_mutex); AssertFatal(!ret, "mutex failed %d\n", ret); @@ -1713,10 +1779,13 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up mac->sc_info.initial_ul_BWPStart = bwp->BWPStart; } if (ul_common->rach_ConfigCommon) { - HANDLE_SETUPRELEASE_DIRECT(bwp->rach_ConfigCommon, - ul_common->rach_ConfigCommon, - NR_RACH_ConfigCommon_t, - asn_DEF_NR_RACH_ConfigCommon); + // ssb_perRACH_OccasionAndCB_PreamblesPerSSB is need M + // if NULL we need to maintain the information + NR_SetupRelease_RACH_ConfigCommon_t *rachcommon = ul_common->rach_ConfigCommon; + if (rachcommon->present == NR_SetupRelease_RACH_ConfigCommon_PR_setup + && rachcommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB) + mac->ssb_ro_preambles = get_ssb_ro_preambles_4step(rachcommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB); + HANDLE_SETUPRELEASE_DIRECT(bwp->rach_ConfigCommon, rachcommon, NR_RACH_ConfigCommon_t, asn_DEF_NR_RACH_ConfigCommon); } if (ul_common->ext1 && ul_common->ext1->msgA_ConfigCommon_r16) { HANDLE_SETUPRELEASE_DIRECT(bwp->msgA_ConfigCommon_r16, @@ -1804,7 +1873,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t LOG_A(NR_MAC, "Received detach indication\n"); reset_ra(mac, true); reset_mac_inst(mac); - nr_ue_reset_sync_state(mac); + nr_ue_reset_sync_state(mac, false); release_mac_configuration(mac, cause); mac->state = UE_DETACHING; break; @@ -1821,7 +1890,7 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t case RE_ESTABLISHMENT: reset_mac_inst(mac); nr_ue_mac_default_configs(mac); - nr_ue_reset_sync_state(mac); + nr_ue_reset_sync_state(mac, true); release_mac_configuration(mac, cause); // suspend all RBs except SRB0 for (int j = 0; j < mac->lc_ordered_list.count; j++) { @@ -1943,11 +2012,12 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *si mac->state = UE_PERFORMING_RA; mac->if_module->phy_config_request(&mac->phy_config); + mac->phy_config.config_req.ntn_config.params_changed = false; ret = pthread_mutex_unlock(&mac->if_mutex); AssertFatal(!ret, "mutex failed %d\n", ret); } -void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19, bool can_start_ra) +void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19, int hfn, int frame, bool can_start_ra) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); int ret = pthread_mutex_lock(&mac->if_mutex); @@ -1956,7 +2026,9 @@ void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19, b if (sib19) { // update ntn_Config_r17 with received values UPDATE_IE(mac->sc_info.ntn_Config_r17, sib19->ntn_Config_r17, NR_NTN_Config_r17_t); - configure_ntn_ta(mac->ue_id, &mac->ntn_ta, mac->sc_info.ntn_Config_r17); + configure_ntn_ta(&mac->phy_config.config_req.ntn_config, mac->sc_info.ntn_Config_r17, hfn, frame, false); + mac->if_module->phy_config_request(&mac->phy_config); + mac->phy_config.config_req.ntn_config.params_changed = false; } if (mac->state == UE_RECEIVING_SIB && can_start_ra) mac->state = UE_PERFORMING_RA; @@ -1966,6 +2038,8 @@ void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19, b static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, int cc_idP, + int hfn, + int frame, const NR_ReconfigurationWithSync_t *reconfWithSync) { reset_mac_inst(mac); @@ -1973,19 +2047,30 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, LOG_I(NR_MAC, "Configuring CRNTI %x\n", mac->crnti); RA_config_t *ra = &mac->ra; + bool is_cfra = false; if (reconfWithSync->rach_ConfigDedicated) { AssertFatal(reconfWithSync->rach_ConfigDedicated->present == NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink, "RACH on supplementaryUplink not supported\n"); + NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = reconfWithSync->rach_ConfigDedicated->choice.uplink; + if (rach_ConfigDedicated->cfra) + is_cfra = true; + if (rach_ConfigDedicated->ext1 && rach_ConfigDedicated->ext1->cfra_TwoStep_r16) + is_cfra = true; UPDATE_IE(ra->rach_ConfigDedicated, reconfWithSync->rach_ConfigDedicated->choice.uplink, NR_RACH_ConfigDedicated_t); } + // in case of CBRA and reconfiguration with sync (handover) + // the UE sends MSG3 with C-RNTI to identify itself + if (!is_cfra) + mac->msg3_C_RNTI = true; + if (reconfWithSync->spCellConfigCommon) { NR_ServingCellConfigCommon_t *scc = reconfWithSync->spCellConfigCommon; if (scc->physCellId) mac->physCellId = *scc->physCellId; mac->dmrs_TypeA_Position = scc->dmrs_TypeA_Position; UPDATE_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t); - config_common_ue(mac, scc, cc_idP); + config_common_ue(mac, scc, cc_idP, hfn, frame); // Build the list of all the valid/transmitted SSBs according to the config LOG_D(NR_MAC,"Build SSB list\n"); build_ssb_list(mac); @@ -1997,7 +2082,7 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, configure_common_BWP_ul(mac, bwp_id, scc->uplinkConfigCommon->initialUplinkBWP); } - mac->state = UE_NOT_SYNC; + mac->state = UE_NOT_SYNC_RECONF; ra->ra_state = nrRA_UE_IDLE; nr_ue_mac_default_configs(mac); @@ -2006,6 +2091,7 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, mac->synch_request.synch_req.target_Nid_cell = mac->physCellId; mac->if_module->synch_request(&mac->synch_request); mac->if_module->phy_config_request(&mac->phy_config); + mac->phy_config.config_req.ntn_config.params_changed = false; } static void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac, @@ -2754,6 +2840,8 @@ static void handle_mac_uecap_info(NR_UE_MAC_INST_t *mac, NR_UE_NR_Capability_t * void nr_rrc_mac_config_req_cg(module_id_t module_id, int cc_idP, + int hfn, + int frame, NR_CellGroupConfig_t *cell_group_config, NR_UE_NR_Capability_t *ue_Capability) { @@ -2772,7 +2860,7 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id, mac->servCellIndex = spCellConfig->servCellIndex ? *spCellConfig->servCellIndex : 0; if (spCellConfig->reconfigurationWithSync) { LOG_A(NR_MAC, "Received reconfigurationWithSync\n"); - handle_reconfiguration_with_sync(mac, cc_idP, spCellConfig->reconfigurationWithSync); + handle_reconfiguration_with_sync(mac, cc_idP, hfn, frame, spCellConfig->reconfigurationWithSync); } if (scd) { mac->tag_Id = scd->tag_Id; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index b43937d362..65bf66505b 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -62,6 +62,8 @@ #include "NR_MeasConfig.h" #include "NR_ServingCellConfigCommonSIB.h" +/* position_t */ +#include "executables/position_interface.h" // ========== // NR UE defs @@ -148,6 +150,7 @@ // Define the UE L2 states with X-Macro #define NR_UE_L2_STATES \ UE_STATE(UE_NOT_SYNC) \ + UE_STATE(UE_NOT_SYNC_RECONF) \ UE_STATE(UE_BARRED) \ UE_STATE(UE_RECEIVING_SIB) \ UE_STATE(UE_PERFORMING_RA) \ @@ -542,28 +545,6 @@ typedef struct { A_SEQUENCE_OF(si_schedinfo_config_t) si_SchedInfo_list; } si_schedInfo_t; -typedef struct ntn_timing_advance_components { - int epoch_sfn; - int epoch_subframe; - - // N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms) - double N_common_ta_adj; - // drift rate of common ta in µs/s - double N_common_ta_drift; - // change rate of common ta drift in µs/s² - double N_common_ta_drift_variant; - // N_UE_TA_adj calculated round-trip-time between UE and SAT (ms) - double N_UE_TA_adj; - // drift rate of N_UE_TA in µs/s - double N_UE_TA_drift; - // change rate of N_UE_TA drift in µs/s² - double N_UE_TA_drift_variant; - // cell scheduling offset expressed in terms of 15kHz SCS - long cell_specific_k_offset; - - bool ntn_params_changed; -} ntn_timing_advance_componets_t; - /*!\brief Top level UE MAC structure */ typedef struct NR_UE_MAC_INST_s { module_id_t ue_id; @@ -627,8 +608,6 @@ typedef struct NR_UE_MAC_INST_s { int p_Max; int p_Max_alt; - ntn_timing_advance_componets_t ntn_ta; - long pdsch_HARQ_ACK_Codebook; NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config; @@ -639,6 +618,7 @@ typedef struct NR_UE_MAC_INST_s { NR_SSB_meas_t ssb_measurements[MAX_NB_SSB]; NR_CSIRS_meas_t csirs_measurements; + ssb_ro_preambles_t ssb_ro_preambles; dci_pdu_rel15_t def_dci_pdu_rel15[NR_MAX_SLOTS_PER_FRAME][8]; @@ -668,30 +648,15 @@ typedef struct NR_UE_MAC_INST_s { notifiedFIFO_t input_nf; } NR_UE_MAC_INST_t; -static inline int GET_NTN_UE_K_OFFSET(const ntn_timing_advance_componets_t *ntn_ta, int scs) +static inline int GET_NTN_UE_K_OFFSET(const fapi_nr_ntn_config_t *ntn_ta, int scs) { return (int)ntn_ta->cell_specific_k_offset << scs; } -static inline long GET_DURATION_RX_TO_TX(const ntn_timing_advance_componets_t *ntn_ta, int scs) +static inline long GET_DURATION_RX_TO_TX(const fapi_nr_ntn_config_t *ntn_ta, int scs) { return NR_UE_CAPABILITY_SLOT_RX_TO_TX + (ntn_ta->cell_specific_k_offset << scs); } -static inline double get_total_TA_ms(const ntn_timing_advance_componets_t *ntn_ta) -{ - return ntn_ta->N_common_ta_adj + ntn_ta->N_UE_TA_adj; -} - -static inline double get_total_TA_drift(const ntn_timing_advance_componets_t *ntn_ta) -{ - return ntn_ta->N_common_ta_drift + ntn_ta->N_UE_TA_drift; -} - -static inline double get_total_TA_drift_variant(const ntn_timing_advance_componets_t *ntn_ta) -{ - return ntn_ta->N_common_ta_drift_variant + ntn_ta->N_UE_TA_drift_variant; -} - /*@}*/ #endif /*__LAYER2_MAC_DEFS_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 4897a8fab8..5ee8a62625 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -73,6 +73,7 @@ void nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, uint8_t ack_nack, uint8_t *pduP, uint32_t pdu_len, + int hfn, int frame, int slot); @@ -82,15 +83,17 @@ void nr_release_mac_config_logicalChannelBearer(NR_UE_MAC_INST_t *mac, long chan void nr_rrc_mac_config_req_cg(module_id_t module_id, int cc_idP, + int hfn, + int frame, NR_CellGroupConfig_t *cell_group_config, NR_UE_NR_Capability_t *ue_Capability); -void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mibP, int sched_sib1, bool barred); - +void nr_rrc_mac_config_req_mib(module_id_t module_id, int cc_idP, NR_MIB_t *mibP, bool barred); +void nr_rrc_mac_sched_sib(module_id_t module_id, int sched_sib); void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *sib1, bool can_start_ra); struct position; /* forward declaration */ -void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19_r17, bool can_start_ra); +void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19_r17, int hfn, int frame, bool can_start_ra); void nr_rrc_mac_resume_rb(module_id_t module_id, bool is_srb, int rb_id); void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause); @@ -252,7 +255,7 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac); void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack); void configure_initial_pucch(PUCCH_sched_t *pucch, int res_ind); void release_PUCCH_SRS(NR_UE_MAC_INST_t *mac); -void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac); +void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac, bool reconf); void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int cc_id, const fapi_nr_synch_request_t *sync_req); bool is_ss_monitor_occasion(const int frame, const int slot, const int slots_per_frame, const NR_SearchSpace_t *ss); @@ -360,5 +363,5 @@ int sl_nr_ue_slot_select(const sl_nr_phy_config_request_t *cfg, int nr_slot, uin void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t *mac); NR_SearchSpace_t *get_common_search_space(const NR_UE_MAC_INST_t *mac, const NR_SearchSpaceId_t ss_id); - +ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config); #endif diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index c78d2217b4..461d21f3aa 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -54,7 +54,7 @@ void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) { LOG_I(NR_MAC, "[UE%d] Initializing MAC\n", mac->ue_id); - nr_ue_reset_sync_state(mac); + nr_ue_reset_sync_state(mac, false); mac->get_sib1 = false; for (int i = 0; i < MAX_SI_GROUPS; i++) mac->get_otherSI[i] = false; @@ -69,7 +69,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) mac->p_Max = INT_MIN; mac->p_Max_alt = INT_MIN; mac->msg3_C_RNTI = false; - mac->ntn_ta.ntn_params_changed = false; + mac->phy_config.config_req.ntn_config.params_changed = false; initNotifiedFIFO(&mac->input_nf); reset_mac_inst(mac); @@ -117,10 +117,10 @@ void nr_ue_send_synch_request(NR_UE_MAC_INST_t *mac, module_id_t module_id, int mac->if_module->synch_request(&mac->synch_request); } -void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac) +void nr_ue_reset_sync_state(NR_UE_MAC_INST_t *mac, bool reconf) { // reset synchornization status - mac->state = UE_NOT_SYNC; + mac->state = reconf ? UE_NOT_SYNC_RECONF : UE_NOT_SYNC; mac->ra.ra_state = nrRA_UE_IDLE; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 0dae34eda7..47277f8a66 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -190,7 +190,7 @@ static void select_preamble_group(NR_UE_MAC_INST_t *mac) // else if Msg3 is being retransmitted, we keep what used in first transmission of Msg3 } -static ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config) +ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config) { ssb_ro_preambles_t ret = {0}; switch (config->present) { @@ -293,9 +293,7 @@ static void config_preamble_index(NR_UE_MAC_INST_t *mac) bool groupBconfigured = false; int preamb_ga = 0; if (ra->ra_type == RA_4_STEP) { - AssertFatal(nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB, - "Not expeting ssb_perRACH_OccasionAndCB_PreamblesPerSSB to be NULL here\n"); - ra->ssb_ro_config = get_ssb_ro_preambles_4step(nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB); + ra->ssb_ro_config = mac->ssb_ro_preambles; if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles) nb_of_preambles = *nr_rach_ConfigCommon->totalNumberOfRA_Preambles; // Amongst the contention-based Random Access Preambles associated with an SSB the first numberOfRA-PreamblesGroupA @@ -321,7 +319,7 @@ static void config_preamble_index(NR_UE_MAC_INST_t *mac) if (twostep->msgA_SSB_PerRACH_OccasionAndCB_PreamblesPerSSB_r16) ra->ssb_ro_config = get_ssb_ro_preambles_2step(twostep->msgA_SSB_PerRACH_OccasionAndCB_PreamblesPerSSB_r16); else - ra->ssb_ro_config = get_ssb_ro_preambles_4step(nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB); + ra->ssb_ro_config = mac->ssb_ro_preambles; if (twostep->msgA_TotalNumberOfRA_Preambles_r16) nb_of_preambles = *twostep->msgA_TotalNumberOfRA_Preambles_r16; } @@ -777,13 +775,12 @@ static int nr_get_RA_window_4Step(long ra_ResponseWindow) return 0; } -static void setup_ra_response_window(RA_config_t *ra, - int slots_per_frame, - NR_NTN_Config_r17_t *ntn_Config_r17, +static void setup_ra_response_window(NR_UE_MAC_INST_t *mac, + RA_config_t *ra, NR_RACH_ConfigGeneric_t *configGeneric, - NR_RACH_ConfigGenericTwoStepRA_r16_t *twostep, - ntn_timing_advance_componets_t *ntn_ta) + NR_RACH_ConfigGenericTwoStepRA_r16_t *twostep) { + const int slots_per_frame = mac->frame_structure.numb_slots_frame; int respwind_value = 0; if (ra->ra_type == RA_2_STEP) { long *msgB_ResponseWindow = twostep->msgB_ResponseWindow_r16; @@ -816,13 +813,8 @@ static void setup_ra_response_window(RA_config_t *ra, LOG_E(NR_MAC, "RA-ResponseWindow need to be configured to a value lower than or equal to 10 ms\n"); } - int ta_Common_slots = 0; - if (ntn_Config_r17) { - const double ta_Common_ms = get_total_TA_ms(ntn_ta); - ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_frame / 10); - } - - ra->response_window_setup_time = respwind_value + ta_Common_slots; + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs); + ra->response_window_setup_time = respwind_value + ntn_ue_koffset; } // Random Access procedure initialization as per 5.1.1 and initialization of variables specific @@ -1026,12 +1018,8 @@ bool init_RA(NR_UE_MAC_INST_t *mac, int frame) else ra->num_fd_occasions = 1 << rach_ConfigGeneric->msg1_FDM; - setup_ra_response_window(ra, - mac->frame_structure.numb_slots_frame, - mac->sc_info.ntn_Config_r17, - rach_ConfigGeneric, - twostep_generic, - &mac->ntn_ta); + setup_ra_response_window(mac, ra, rach_ConfigGeneric, twostep_generic); + return true; } @@ -1039,16 +1027,15 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s { RA_config_t *ra = &mac->ra; NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon; - const double ta_Common_ms = get_total_TA_ms(&mac->ntn_ta); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs); const int slots_per_ms = mac->frame_structure.numb_slots_frame / 10; // start contention resolution timer const int RA_contention_resolution_timer_ms = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) << 3; const int RA_contention_resolution_timer_slots = RA_contention_resolution_timer_ms * slots_per_ms; - const int ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_ms); // timer step 1 slot and timer target given by ra_ContentionResolutionTimer + ta-Common-r17 - nr_timer_setup(&ra->contention_resolution_timer, RA_contention_resolution_timer_slots + ta_Common_slots, 1); + nr_timer_setup(&ra->contention_resolution_timer, RA_contention_resolution_timer_slots + ntn_ue_koffset, 1); nr_timer_start(&ra->contention_resolution_timer); ra->ra_state = nrRA_WAIT_CONTENTION_RESOLUTION; @@ -1127,9 +1114,9 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame RA_config_t *ra = &mac->ra; if (ra->cfra) { - LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CFRA: RAR successfully received.\n", mac->ue_id, frame, slot); + LOG_A(NR_MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CFRA: RAR successfully received.\n", mac->ue_id, frame, slot); } else { - LOG_A(MAC, + LOG_A(NR_MAC, "[UE %d][%d.%d][RAPROC] %d-Step RA procedure succeeded. CBRA: Contention Resolution is successful.\n", mac->ue_id, frame, @@ -1140,6 +1127,10 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame nr_timer_stop(&ra->contention_resolution_timer); } + // rach-ConfigDedicated is one shot configuration to be used only for a specific instance of reconfiguration with sync + if (ra->rach_ConfigDedicated) + asn1cFreeStruc(asn_DEF_NR_RACH_ConfigDedicated, ra->rach_ConfigDedicated); + ra->RA_active = false; mac->msg3_C_RNTI = false; ra->ra_state = nrRA_SUCCEEDED; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 8a2074422e..477e39a60a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -38,7 +38,7 @@ #include "executables/softmodem-common.h" #include -void fill_dci_search_candidates(const NR_SearchSpace_t *ss, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, const uint32_t Y) +static void fill_dci_search_candidates(const NR_SearchSpace_t *ss, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, const uint32_t Y) { LOG_T(NR_MAC_DCI, "Filling search candidates for DCI\n"); @@ -89,7 +89,7 @@ void fill_dci_search_candidates(const NR_SearchSpace_t *ss, fapi_nr_dl_config_dc rel15->number_of_candidates = i; } -NR_ControlResourceSet_t *ue_get_coreset(const NR_BWP_PDCCH_t *config, const int coreset_id) +static NR_ControlResourceSet_t *ue_get_coreset(const NR_BWP_PDCCH_t *config, const int coreset_id) { if (config->commonControlResourceSet && coreset_id == config->commonControlResourceSet->controlResourceSetId) return config->commonControlResourceSet; @@ -122,9 +122,18 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac, if(coreset_id > 0) { coreset = ue_get_coreset(pdcch_config, coreset_id); rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; + if (coreset->ext1 && coreset->ext1->rb_Offset_r16) + rel15->coreset.rb_offset = *coreset->ext1->rb_Offset_r16; + else { + // first common RB of the first group of 6 PRBs has common RB index equal to + // 6 * ⌈BWP_start / 6⌉ if rb-Offset is not provided + int start_common = (current_DL_BWP->BWPStart + 5) / 6 * 6; + rel15->coreset.rb_offset = start_common - current_DL_BWP->BWPStart; + } } else { coreset = mac->coreset0; rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; + rel15->coreset.rb_offset = 0; } rel15->coreset.duration = coreset->duration; @@ -198,7 +207,6 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac, NR_UL_DCI_FORMAT_0_0, rnti_type, coreset, - dl_bwp_id, ss->searchSpaceType->present, mac->type0_PDCCH_CSS_config.num_rbs, 0); @@ -211,7 +219,6 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac, NR_DL_DCI_FORMAT_1_0, rnti_type, coreset, - dl_bwp_id, ss->searchSpaceType->present, mac->type0_PDCCH_CSS_config.num_rbs, 0); @@ -225,7 +232,6 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac, dci_format[i], rnti_type, coreset, - dl_bwp_id, ss->searchSpaceType->present, mac->type0_PDCCH_CSS_config.num_rbs, alt_size); @@ -356,12 +362,12 @@ bool is_ss_monitor_occasion(const int frame, const int slot, const int slots_per return monitor; } -bool search_space_monitoring_ocasion_other_si(NR_UE_MAC_INST_t *mac, - const NR_SearchSpace_t *ss, - const int abs_slot, - const int frame, - const int slot, - const int slots_per_frame) +static bool search_space_monitoring_ocasion_other_si(NR_UE_MAC_INST_t *mac, + const NR_SearchSpace_t *ss, + const int abs_slot, + const int frame, + const int slot, + const int slots_per_frame) { const int duration = ss->duration ? *ss->duration : 1; int period, offset; @@ -483,6 +489,15 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl } config_dci_pdu(mac, dl_config, rnti_type, slot, ra_SS); } + // If Msg3 has C-RNTI MAC CE, also monitor dedicated search spaces during contention resolution + // according to TS 38.321 section 5.1.5 + if (ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION && mac->msg3_C_RNTI) { + for (int i = 0; i < pdcch_config->list_SS.count; i++) { + NR_SearchSpace_t *ss = pdcch_config->list_SS.array[i]; + if (is_ss_monitor_occasion(frame, slot, slots_per_frame, ss)) + config_dci_pdu(mac, dl_config, TYPE_C_RNTI_, slot, ss); + } + } } else if (mac->state == UE_CONNECTED) { /* In RRC Connected state, the UE monitors for fallback DCI with C-RNTI in common and UE-specific SS. diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index 860089165f..a409cbe653 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -58,13 +58,6 @@ static const int nb_symbols_excluding_dmrs[11][2][2] /* 14 */ {{ 12 , 12 } , { 10 , 10 }}, }; -static int get_deltatf(uint16_t nb_of_prbs, - uint8_t N_symb_PUCCH, - uint8_t freq_hop_flag, - uint8_t add_dmrs_flag, - int N_sc_ctrl_RB, - int O_UCI); - // ∆MPR according to Table 6.2.2-3 38.101-1 static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int channel_bandwidth, int n_prbs, int start_prb, int power_class) { @@ -256,6 +249,28 @@ int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame) return delta_tpc_sum; } +static int get_deltatf(uint16_t nb_of_prbs, + uint8_t N_symb_PUCCH, + uint8_t freq_hop_flag, + uint8_t add_dmrs_flag, + int N_sc_ctrl_RB, + int O_UCI) +{ + int DELTA_TF; + int O_CRC = compute_pucch_crc_size(O_UCI); + int N_symb = N_symb_PUCCH < 4 ? N_symb_PUCCH : nb_symbols_excluding_dmrs[N_symb_PUCCH - 4][add_dmrs_flag][freq_hop_flag]; + float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb; + float K1 = 6; + if (O_UCI + O_CRC < 12) + DELTA_TF = 10 * log10((double)(((K1 * (O_UCI)) / N_RE))); + else { + float K2 = 2.4; + float BPRE = (O_UCI + O_CRC) / N_RE; + DELTA_TF = 10 * log10((double)(pow(2, (K2 * BPRE)) - 1)); + } + return DELTA_TF; +} + // PUCCH Power control according to 38.213 section 7.2.1 int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, int scs, @@ -399,28 +414,6 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, return pucch_power; } -static int get_deltatf(uint16_t nb_of_prbs, - uint8_t N_symb_PUCCH, - uint8_t freq_hop_flag, - uint8_t add_dmrs_flag, - int N_sc_ctrl_RB, - int O_UCI) -{ - int DELTA_TF; - int O_CRC = compute_pucch_crc_size(O_UCI); - int N_symb = N_symb_PUCCH < 4 ? N_symb_PUCCH : nb_symbols_excluding_dmrs[N_symb_PUCCH - 4][add_dmrs_flag][freq_hop_flag]; - float N_RE = nb_of_prbs * N_sc_ctrl_RB * N_symb; - float K1 = 6; - if (O_UCI + O_CRC < 12) - DELTA_TF = 10 * log10((double)(((K1 * (O_UCI)) / N_RE))); - else { - float K2 = 2.4; - float BPRE = (O_UCI + O_CRC) / N_RE; - DELTA_TF = 10 * log10((double)(pow(2, (K2 * BPRE)) - 1)); - } - return DELTA_TF; -} - // Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission // computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16 // Assumptions: diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index aeb15fe864..3ba221386f 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -104,58 +104,7 @@ static const int sequence_cyclic_shift_2_harq_ack_bits[4] /* HARQ-ACK Value (0,0) (0,1) (1,0) (1,1) */ /* Sequence cyclic shift */ = { 0, 3, 9, 6 }; -/* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It -provides the timing advance and t-CRNTI. -@param Mod_id Index of UE instance -@param CC_id Index to a component carrier -@param frame Frame index -@param ra_rnti RA_RNTI value -@param dlsch_buffer Pointer to dlsch_buffer containing RAR PDU -@param t_crnti Pointer to PHY variable containing the T_CRNTI -@param preamble_index Preamble Index used by PHY to transmit the PRACH. This should match the received RAR to trigger the rest of -random-access procedure -@param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload -@returns timing advance or 0xffff if preamble doesn't match -*/ -static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id); - -/*! \fn int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id); - \brief This function schedules a positive or negative SR for schedulingRequestID sr_id - depending on the presence of any active SR and the prohibit timer. - If the max number of retransmissions is reached, it triggers a new RA */ -static int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id); - -static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, - struct NR_CSI_ReportConfig *csi_reportconfig, - NR_CSI_ResourceConfigId_t csi_ResourceConfigId, - NR_CSI_MeasConfig_t *csi_MeasConfig); - -static csi_payload_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, - struct NR_CSI_ReportConfig *csi_reportconfig, - NR_CSI_ResourceConfigId_t csi_ResourceConfigId, - NR_CSI_MeasConfig_t *csi_MeasConfig, - CSI_mapping_t mapping_type); -static csi_payload_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, - struct NR_CSI_ReportConfig *csi_reportconfig, - NR_CSI_ResourceConfigId_t csi_ResourceConfigId, - const NR_CSI_MeasConfig_t *csi_MeasConfig); - -static uint8_t get_rsrp_diff_index(int best_rsrp, int current_rsrp); - -static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id); - -static void set_harq_status(NR_UE_MAC_INST_t *mac, - uint8_t pucch_id, - uint8_t harq_id, - int8_t delta_pucch, - uint16_t data_toul_fb, - uint8_t dai, - int n_CCE, - int N_CCE, - frame_t frame, - int slot); - -int get_pucch0_mcs(const int O_ACK, const int O_SR, const int ack_payload, const int sr_payload) +static int get_pucch0_mcs(const int O_ACK, const int O_SR, const int ack_payload, const int sr_payload) { int mcs = 0; if (O_SR == 0 || sr_payload == 0) { /* only ack is transmitted TS 36.213 9.2.3 UE procedure for reporting HARQ-ACK */ @@ -197,14 +146,6 @@ const initial_pucch_resource_t initial_pucch_resource[16] = { /* 15 */ { 1, 0, 14, 0, 4, { 0, 3, 6, 9 } }, }; -static nr_dci_format_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, - const nfapi_nr_dci_formats_e dci_format, - const uint8_t dci_size, - const uint16_t rnti, - const int ss_type, - const uint8_t *dci_pdu, - const int slot); - int get_rnti_type(const NR_UE_MAC_INST_t *mac, const uint16_t rnti) { const RA_config_t *ra = &mac->ra; @@ -361,12 +302,13 @@ void nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, uint8_t ack_nack, uint8_t *pduP, uint32_t pdu_len, + int hfn, int frame, int slot) { if(ack_nack) { LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); - nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, frame, slot, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); + nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, hfn, frame, slot, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); if (mac->get_sib1) mac->get_sib1 = false; for (int i = 0; i < MAX_SI_GROUPS; i++) { @@ -383,7 +325,7 @@ void nr_ue_decode_BCCH_DL_SCH(NR_UE_MAC_INST_t *mac, } else { LOG_E(NR_MAC, "Got NACK on NR-BCCH-DL-SCH-Message (%s)\n", mac->get_sib1 ? "SIB1" : "other SI"); - nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, frame, slot, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, NULL, 0); + nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, hfn, frame, slot, 0, mac->physCellId, 0, NR_BCCH_DL_SCH, NULL, 0); } } @@ -522,6 +464,71 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p return 0; } +static void set_harq_status(NR_UE_MAC_INST_t *mac, + uint8_t pucch_id, + uint8_t harq_id, + int8_t delta_pucch, + uint16_t data_toul_fb, + uint8_t dai, + int n_CCE, + int N_CCE, + frame_t frame, + int slot) +{ + NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_id]; + current_harq->active = true; + current_harq->ack_received = false; + current_harq->pucch_resource_indicator = pucch_id; + current_harq->n_CCE = n_CCE; + current_harq->N_CCE = N_CCE; + current_harq->dai_cumul = 0; + current_harq->delta_pucch = delta_pucch; + // FIXME k0 != 0 currently not taken into consideration + int slots_per_frame = mac->frame_structure.numb_slots_frame; + current_harq->ul_frame = frame; + current_harq->ul_slot = slot + data_toul_fb; + if (current_harq->ul_slot >= slots_per_frame) { + current_harq->ul_frame = (frame + current_harq->ul_slot / slots_per_frame) % MAX_FRAME_NUMBER; + current_harq->ul_slot %= slots_per_frame; + } + // counter DAI in DCI ranges from 0 to 3 + // we might have more than 4 HARQ processes to report per PUCCH + // we need to keep track of how many DAI we received in a slot (dai_cumul) despite the modulo operation + int highest_dai = -1; + int temp_dai = dai; + const int num_dl_harq = get_nrofHARQ_ProcessesForPDSCH(&mac->sc_info); + for (int i = 0; i < num_dl_harq; i++) { + // looking for other active HARQ processes with feedback in the same frame/slot + if (i == harq_id) + continue; + NR_UE_DL_HARQ_STATUS_t *harq = &mac->dl_harq_info[i]; + if (harq->active && + harq->ul_frame == current_harq->ul_frame && + harq->ul_slot == current_harq->ul_slot) { + // highest_dai is the largest cumulative dai in the set of HARQ allocations for a given slot + if (harq->dai_cumul > highest_dai) + highest_dai = harq->dai_cumul - 1; + } + } + + current_harq->dai_cumul = temp_dai + 1; // DAI = 0 (temp_dai) corresponds to 1st assignment and so on + // if temp_dai is less or equal than cumulative highest dai for given slot + // it's an indication dai was reset due to modulo 4 operation + if (temp_dai <= highest_dai) { + int mod4_count = (highest_dai + 1) / 4; // to take into account how many times dai wrapped up (modulo 4) + current_harq->dai_cumul += (mod4_count * 4); + } + LOG_D(NR_MAC, + "Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d fb time %d total dai %d\n", + harq_id, + frame, + slot, + current_harq->ul_frame, + current_harq->ul_slot, + data_toul_fb, + current_harq->dai_cumul); +} + static int nr_ue_process_dci_ul_00(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, @@ -562,7 +569,7 @@ static int nr_ue_process_dci_ul_00(NR_UE_MAC_INST_t *mac, frame_t frame_tx; int slot_tx; - const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs); if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset)) { LOG_E(MAC, "Cannot schedule PUSCH\n"); return -1; @@ -660,7 +667,7 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac, tda_info.k2 = csi_K2; } - const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs); if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset)) { LOG_E(MAC, "Cannot schedule PUSCH\n"); return -1; @@ -997,7 +1004,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */ // according to TS 38.213 9.2.3 - const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing); uint16_t feedback_ti = 0; if (rnti_type == TYPE_RA_RNTI_) { @@ -1005,17 +1012,17 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, // that can process the MSG3. Also assume that RAR is sent in the same slot as DCI (k0 == 0) // This is not perfect as the MSG3 might end up being scheduled later, so we could be // halting the UL scheduler for a longer time than necessary. - feedback_ti = max(1 + GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing), + feedback_ti = max(1 + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing), get_delta_for_k2(mac->current_UL_BWP->scs) + get_j_for_k2(mac->current_UL_BWP->scs)); } if (rnti_type != TYPE_RA_RNTI_ && rnti_type != TYPE_SI_RNTI_) { if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) { feedback_ti = 1 + dci->pdsch_to_harq_feedback_timing_indicator.val + ntn_ue_koffset; - AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing), + AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing), "PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld).\n", feedback_ti, - GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing)); + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing)); // set the harq status at MAC for feedback const int tpc[] = {-1, 0, 1, 3}; set_harq_status(mac, @@ -1311,16 +1318,16 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac, /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */ // according to TS 38.213 Table 9.2.3-1 - const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing); uint16_t feedback_ti = 0; if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) { feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0] + ntn_ue_koffset; - AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing), + AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing), "PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld). Min feedback time set in config " "file (min_rxtxtime).\n", feedback_ti, - GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing)); + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing)); // set the harq status at MAC for feedback const int tpc[] = {-1, 0, 1, 3}; @@ -1485,27 +1492,6 @@ static int8_t nr_ue_process_dci(NR_UE_MAC_INST_t *mac, return -1; } -nr_dci_format_t nr_ue_process_dci_indication_pdu(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) -{ - LOG_D(NR_MAC, - "Received dci indication (rnti %x, dci format %d, n_CCE %d, payloadSize %d, payload %llx)\n", - dci->rnti, - dci->dci_format, - dci->n_CCE, - dci->payloadSize, - *(unsigned long long *)dci->payloadBits); - const nr_dci_format_t format = - nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, dci->payloadBits, slot); - if (format == NR_DCI_NONE) - return NR_DCI_NONE; - int ret = nr_ue_process_dci(mac, frame, slot, mac->def_dci_pdu_rel15[slot] + format, dci, format); - if (ret < 0) { - mac->stats.bad_dci++; - return NR_DCI_NONE; - } - return format; -} - void nr_ue_process_l1_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, fapi_nr_l1_measurements_t *l1_measurements) { LOG_D(NR_MAC, "(%d.%d) Received measurements from L1\n", frame, slot); @@ -1529,71 +1515,6 @@ void nr_ue_process_l1_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slo l1_measurements->rsrp_dBm); } -static void set_harq_status(NR_UE_MAC_INST_t *mac, - uint8_t pucch_id, - uint8_t harq_id, - int8_t delta_pucch, - uint16_t data_toul_fb, - uint8_t dai, - int n_CCE, - int N_CCE, - frame_t frame, - int slot) -{ - NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_id]; - current_harq->active = true; - current_harq->ack_received = false; - current_harq->pucch_resource_indicator = pucch_id; - current_harq->n_CCE = n_CCE; - current_harq->N_CCE = N_CCE; - current_harq->dai_cumul = 0; - current_harq->delta_pucch = delta_pucch; - // FIXME k0 != 0 currently not taken into consideration - int slots_per_frame = mac->frame_structure.numb_slots_frame; - current_harq->ul_frame = frame; - current_harq->ul_slot = slot + data_toul_fb; - if (current_harq->ul_slot >= slots_per_frame) { - current_harq->ul_frame = (frame + current_harq->ul_slot / slots_per_frame) % MAX_FRAME_NUMBER; - current_harq->ul_slot %= slots_per_frame; - } - // counter DAI in DCI ranges from 0 to 3 - // we might have more than 4 HARQ processes to report per PUCCH - // we need to keep track of how many DAI we received in a slot (dai_cumul) despite the modulo operation - int highest_dai = -1; - int temp_dai = dai; - const int num_dl_harq = get_nrofHARQ_ProcessesForPDSCH(&mac->sc_info); - for (int i = 0; i < num_dl_harq; i++) { - // looking for other active HARQ processes with feedback in the same frame/slot - if (i == harq_id) - continue; - NR_UE_DL_HARQ_STATUS_t *harq = &mac->dl_harq_info[i]; - if (harq->active && - harq->ul_frame == current_harq->ul_frame && - harq->ul_slot == current_harq->ul_slot) { - // highest_dai is the largest cumulative dai in the set of HARQ allocations for a given slot - if (harq->dai_cumul > highest_dai) - highest_dai = harq->dai_cumul - 1; - } - } - - current_harq->dai_cumul = temp_dai + 1; // DAI = 0 (temp_dai) corresponds to 1st assignment and so on - // if temp_dai is less or equal than cumulative highest dai for given slot - // it's an indication dai was reset due to modulo 4 operation - if (temp_dai <= highest_dai) { - int mod4_count = (highest_dai + 1) / 4; // to take into account how many times dai wrapped up (modulo 4) - current_harq->dai_cumul += (mod4_count * 4); - } - LOG_D(NR_MAC, - "Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d fb time %d total dai %d\n", - harq_id, - frame, - slot, - current_harq->ul_frame, - current_harq->ul_slot, - data_toul_fb, - current_harq->dai_cumul); -} - initial_pucch_resource_t get_initial_pucch_resource(const int idx) { return initial_pucch_resource[idx]; @@ -2565,51 +2486,11 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche return (number_harq_feedback > 0); } -bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, frame_t frame, int slot) -{ - NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; - NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL; - - if(!pucch_Config || - !pucch_Config->schedulingRequestResourceToAddModList || - pucch_Config->schedulingRequestResourceToAddModList->list.count == 0) - return false; // SR not configured - - int sr_count = 0; - for (int id = 0; id < pucch_Config->schedulingRequestResourceToAddModList->list.count; id++) { - NR_SchedulingRequestResourceConfig_t *sr_Config = pucch_Config->schedulingRequestResourceToAddModList->list.array[id]; - int SR_period; int SR_offset; - - find_period_offset_SR(sr_Config, &SR_period, &SR_offset); - const int n_slots_frame = mac->frame_structure.numb_slots_frame; - int sfn_sf = frame * n_slots_frame + slot; - - if ((sfn_sf - SR_offset) % SR_period == 0) { - LOG_D(MAC, "Scheduling Request active in frame %d slot %d \n", frame, slot); - if (!sr_Config->resource) { - LOG_E(MAC, "No resource associated with SR. SR not scheduled\n"); - break; - } - NR_PUCCH_Resource_t *sr_pucch = - find_pucch_resource_from_list(pucch_Config->resourceToAddModList, *sr_Config->resource); - AssertFatal(sr_pucch != NULL, "Couldn't find PUCCH Resource ID for SR in PUCCH resource list\n"); - pucch->pucch_resource = sr_pucch; - pucch->n_sr = 1; - /* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */ - int ret = nr_ue_get_SR(mac, frame, slot, sr_Config->schedulingRequestID); - if (ret < 0) { - memset(pucch, 0, sizeof(*pucch)); - return false; - } - pucch->sr_payload = ret; - sr_count++; - AssertFatal(sr_count < 2, "Cannot handle more than 1 SR per slot yet\n"); - } - } - return sr_count > 0; -} - -static int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id) +/*! \fn int nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id); + \brief This function schedules a positive or negative SR for schedulingRequestID sr_id + depending on the presence of any active SR and the prohibit timer. + If the max number of retransmissions is reached, it triggers a new RA */ +static int nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id) { // no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti NR_UE_SCHEDULING_INFO *si = &mac->scheduling_info; @@ -2659,6 +2540,50 @@ static int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR return -1; } +bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, frame_t frame, int slot) +{ + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL; + + if(!pucch_Config || + !pucch_Config->schedulingRequestResourceToAddModList || + pucch_Config->schedulingRequestResourceToAddModList->list.count == 0) + return false; // SR not configured + + int sr_count = 0; + for (int id = 0; id < pucch_Config->schedulingRequestResourceToAddModList->list.count; id++) { + NR_SchedulingRequestResourceConfig_t *sr_Config = pucch_Config->schedulingRequestResourceToAddModList->list.array[id]; + int SR_period; int SR_offset; + + find_period_offset_SR(sr_Config, &SR_period, &SR_offset); + const int n_slots_frame = mac->frame_structure.numb_slots_frame; + int sfn_sf = frame * n_slots_frame + slot; + + if ((sfn_sf - SR_offset) % SR_period == 0) { + LOG_D(MAC, "Scheduling Request active in frame %d slot %d \n", frame, slot); + if (!sr_Config->resource) { + LOG_E(MAC, "No resource associated with SR. SR not scheduled\n"); + break; + } + NR_PUCCH_Resource_t *sr_pucch = + find_pucch_resource_from_list(pucch_Config->resourceToAddModList, *sr_Config->resource); + AssertFatal(sr_pucch != NULL, "Couldn't find PUCCH Resource ID for SR in PUCCH resource list\n"); + pucch->pucch_resource = sr_pucch; + pucch->n_sr = 1; + /* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */ + int ret = nr_ue_get_SR(mac, frame, slot, sr_Config->schedulingRequestID); + if (ret < 0) { + memset(pucch, 0, sizeof(*pucch)); + return false; + } + pucch->sr_payload = ret; + sr_count++; + AssertFatal(sr_count < 2, "Cannot handle more than 1 SR per slot yet\n"); + } + } + return sr_count > 0; +} + // section 5.2.5 of 38.214 int compute_csi_priority(NR_UE_MAC_INST_t *mac, NR_CSI_ReportConfig_t *csirep) { @@ -2854,52 +2779,6 @@ static csi_payload_t get_ssb_sinr_payload(NR_UE_MAC_INST_t *mac, return csi; } -csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, - int csi_report_id, - CSI_mapping_t mapping_type, - NR_CSI_MeasConfig_t *csi_MeasConfig) -{ - AssertFatal(csi_MeasConfig->csi_ReportConfigToAddModList->list.count > 0,"No CSI Report configuration available\n"); - csi_payload_t csi = {0}; - struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; - NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement; - if (csi_reportconfig->ext2 && csi_reportconfig->ext2->reportQuantity_r16) { - switch (csi_reportconfig->ext2->reportQuantity_r16->present) { - case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16: - csi = get_ssb_sinr_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig); - break; - case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_cri_SINR_r16: - LOG_E(NR_MAC, "CSI Reporting of CSI-RS based SINR not yet available\n"); - break; - default: - AssertFatal(1 == 0, "Invalid CSI report quantity r16 type %d\n", csi_reportconfig->ext2->reportQuantity_r16->present); - } - } else { - switch (csi_reportconfig->reportQuantity.present) { - case NR_CSI_ReportConfig__reportQuantity_PR_none: - break; - case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP: - csi = get_ssb_rsrp_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig); - break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: - csi = get_csirs_RI_PMI_CQI_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig, mapping_type); - break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: - csi = get_csirs_RSRP_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig); - break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1: - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI: - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI: - LOG_E(NR_MAC, "Measurement report %d based on CSI-RS is not available\n", csi_reportconfig->reportQuantity.present); - break; - default: - AssertFatal(1 == 0, "Invalid CSI report quantity type %d\n", csi_reportconfig->reportQuantity.present); - } - } - return csi; -} - // Comparison function for sorting SSB RSRP measurements in descending order static int compare_ssb_rsrp(const void *a, const void *b) { @@ -2908,6 +2787,16 @@ static int compare_ssb_rsrp(const void *a, const void *b) return mb->ssb_rsrp_dBm - ma->ssb_rsrp_dBm; } +// returns index from differential RSRP +// according to Table 10.1.6.1-2 in 38.133 +static uint8_t get_rsrp_diff_index(int best_rsrp, int current_rsrp) +{ + int diff = best_rsrp-current_rsrp; + if (diff>30) + return 15; + else + return (diff>>1); +} static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, struct NR_CSI_ReportConfig *csi_reportconfig, @@ -3120,49 +3009,300 @@ static csi_payload_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, return csi; } -// returns index from differential RSRP -// according to Table 10.1.6.1-2 in 38.133 -static uint8_t get_rsrp_diff_index(int best_rsrp, int current_rsrp) +csi_payload_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, + int csi_report_id, + CSI_mapping_t mapping_type, + NR_CSI_MeasConfig_t *csi_MeasConfig) { - int diff = best_rsrp-current_rsrp; - if (diff>30) - return 15; - else - return (diff>>1); + AssertFatal(csi_MeasConfig->csi_ReportConfigToAddModList->list.count > 0,"No CSI Report configuration available\n"); + csi_payload_t csi = {0}; + struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; + NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement; + if (csi_reportconfig->ext2 && csi_reportconfig->ext2->reportQuantity_r16) { + switch (csi_reportconfig->ext2->reportQuantity_r16->present) { + case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16: + csi = get_ssb_sinr_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig); + break; + case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_cri_SINR_r16: + LOG_E(NR_MAC, "CSI Reporting of CSI-RS based SINR not yet available\n"); + break; + default: + AssertFatal(1 == 0, "Invalid CSI report quantity r16 type %d\n", csi_reportconfig->ext2->reportQuantity_r16->present); + } + } else { + switch (csi_reportconfig->reportQuantity.present) { + case NR_CSI_ReportConfig__reportQuantity_PR_none: + break; + case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP: + csi = get_ssb_rsrp_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig); + break; + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: + csi = get_csirs_RI_PMI_CQI_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig, mapping_type); + break; + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: + csi = get_csirs_RSRP_payload(mac, csi_reportconfig, csi_ResourceConfigId, csi_MeasConfig); + break; + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1: + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI: + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI: + LOG_E(NR_MAC, "Measurement report %d based on CSI-RS is not available\n", csi_reportconfig->reportQuantity.present); + break; + default: + AssertFatal(1 == 0, "Invalid CSI report quantity type %d\n", csi_reportconfig->reportQuantity.present); + } + } + return csi; } -void nr_ue_send_sdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id) +static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, int frame, int slot) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment; + ul_time_alignment->ta_command = ta; + ul_time_alignment->ta_apply = type; + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs); + const int n_slots_frame = mac->frame_structure.numb_slots_frame; + ul_time_alignment->frame = (frame + (slot + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER; + ul_time_alignment->slot = (slot + ntn_ue_koffset) % n_slots_frame; + // start or restart the timeAlignmentTimer associated with the indicated TAG + nr_timer_start(&mac->time_alignment_timer); +} - LOG_D(NR_MAC, - "In [%d.%d] Handling DLSCH PDU type %d\n", - dl_info->frame, - dl_info->slot, - dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type); +static void handle_rar_reception(NR_UE_MAC_INST_t *mac, NR_MAC_RAR *rar, frame_t frame, int slot) +{ + RAR_grant_t rar_grant; + RA_config_t *ra = &mac->ra; +#ifdef DEBUG_RAR + // CSI + unsigned char csi_req = (unsigned char)(rar->UL_GRANT_4 & 0x01); +#endif - // Processing MAC PDU - // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs - switch (dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type) { - case FAPI_NR_RX_PDU_TYPE_DLSCH : - // start or restart dataInactivityTimer if any MAC entity receives a MAC SDU for DTCH logical channel, - // DCCH logical channel, or CCCH logical channel - if (mac->data_inactivity_timer) - nr_timer_start(mac->data_inactivity_timer); - // DL data arrival during RRC_CONNECTED when UL synchronisation status is "non-synchronised" - if (!nr_timer_is_active(&mac->time_alignment_timer) && mac->state == UE_CONNECTED && !get_softmodem_params()->phy_test) { - trigger_MAC_UE_RA(mac, NULL); + // TPC + unsigned char tpc_command = (unsigned char)((rar->UL_GRANT_4 >> 1) & 0x07); + ra->Msg3_TPC = (tpc_command << 1) - 6; + + // MCS + rar_grant.mcs = (unsigned char)(rar->UL_GRANT_4 >> 4); + // time alloc + rar_grant.Msg3_t_alloc = (unsigned char)(rar->UL_GRANT_3 & 0x0f); + // frequency alloc + rar_grant.Msg3_f_alloc = (uint16_t)((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12)); + // frequency hopping + rar_grant.freq_hopping = (unsigned char)(rar->UL_GRANT_1 >> 2); + + // Schedule Msg3 + const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; + const NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[current_DL_BWP->bwp_id]; + const NR_SearchSpace_t *ra_SS = get_common_search_space(mac, pdcch_config->ra_SS_id); + NR_tda_info_t tda_info = get_ul_tda_info(current_UL_BWP, + *ra_SS->controlResourceSetId, + ra_SS->searchSpaceType->present, + TYPE_RA_RNTI_, + rar_grant.Msg3_t_alloc); + if (!tda_info.valid_tda || tda_info.nrOfSymbols == 0) { + LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n"); + // resume RAR response window timer if MSG2 decoding failed + nr_timer_suspension(&mac->ra.response_window_timer); + return; + } + frame_t frame_tx = 0; + int slot_tx = 0; + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs); + int ret = nr_ue_pusch_scheduler(mac, 1, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset); + + // TA command + // if the timeAlignmentTimer associated with this TAG is not running + if (!nr_timer_is_active(&mac->time_alignment_timer)) { + const int ta = rar->TA2 + (rar->TA1 << 5); + set_time_alignment(mac, ta, rar_ta, frame_tx, slot_tx); + LOG_W(MAC, "received TA command %d\n", 31 + ta); + } + // else ignore the received Timing Advance Command + +#ifdef DEBUG_RAR + LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E); + LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T); + LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID); + + LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R); + LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1); + + LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2); + LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1); + + LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2); + LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3); + LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4); + + LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1); + LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2); + + LOG_I(NR_MAC, + "[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d\n", + frame, + slot, + mac->ue_id, + rar_grant.Msg3_t_alloc, + rar_grant.Msg3_f_alloc, + ta_command, + rar_grant.mcs, + rar_grant.freq_hopping, + tpc_command); +#endif + + if (ret != -1) { + uint16_t rnti = mac->crnti; + // Upon successful reception, set the T-CRNTI to the RAR value + // if the RA preamble is selected among the contention-based RA Preambles + if (!ra->cfra) { + ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); + rnti = ra->t_crnti; + if (!mac->msg3_C_RNTI) + nr_mac_rrc_msg3_ind(mac->ue_id, rnti, false); + } + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + if (!pdu) + return; + // Config Msg3 PDU + int ret = nr_config_pusch_pdu(mac, + &tda_info, + &pdu->pusch_config_pdu, + NULL, + NULL, + &rar_grant, + rnti, + NR_SearchSpace__searchSpaceType_PR_common, + NR_DCI_NONE); + if (ret != 0) + remove_ul_config_last_item(pdu); + release_ul_config(pdu, false); + } +} + +///////////////////////////////////// +// Random Access Response PDU // +// TS 38.213 ch 8.2 // +// TS 38.321 ch 6.2.3 // +///////////////////////////////////// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise +//| E | T | R A P I D |// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// +//| R | T A |// +//| T A | UL grant |// +//| UL grant |// +//| UL grant |// +//| UL grant |// +//| T C - R N T I |// +//| T C - R N T I |// +///////////////////////////////////// +// UL grant (27 bits) // +///////////////////////////////////// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise +//|-------------------|FHF|F_alloc|// +//| Freq allocation |// +//| F_alloc |Time allocation|// +//| MCS | TPC |CSI|// +///////////////////////////////////// +// TbD WIP Msg3 development ongoing +// - apply UL grant freq alloc & time alloc as per 8.2 TS 38.213 +// - apply tpc command +// WIP fix: +// - time domain indication hardcoded to 0 for k2 offset +// - extend TS 38.213 ch 8.3 Msg3 PUSCH +// - b buffer +// - ulsch power offset +// - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures +static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id) +{ + frame_t frame = dl_info->frame; + int slot = dl_info->slot; + + if(dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack == 0) { + LOG_W(NR_MAC,"[UE %d][RAPROC][%d.%d] CRC check failed on RAR (NAK)\n", mac->ue_id, frame, slot); + return; + } + + RA_config_t *ra = &mac->ra; + ra->t_crnti = 0; + uint8_t n_subPDUs = 0; // number of RAR payloads + uint8_t n_subheaders = 0; // number of MAC RAR subheaders + uint8_t *dlsch_buffer = dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.pdu; + NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer + NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer + uint8_t preamble_index = ra->ra_PreambleIndex; + uint16_t rnti = mac->ra.ra_rnti; + + T(T_NRUE_MAC_DL_RAR_PDU_WITH_DATA, T_INT(rnti), T_INT(frame), T_INT(slot), + T_BUFFER(dlsch_buffer, dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.pdu_length)); + + ra->RA_backoff_limit = 0; + LOG_D(NR_MAC, "[%d.%d]: [UE %d][RAPROC] MAC received RAR (current preamble %d)\n", frame, slot, mac->ue_id, preamble_index); + + while (1) { + n_subheaders++; + if (rarh->T == 1) { + n_subPDUs++; + LOG_I(NR_MAC, "[UE %d][RAPROC][RA-RNTI %04x] Got RAPID RAR subPDU\n", mac->ue_id, rnti); + } else { + int bi_ms = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI] * ra->scaling_factor_bi; + int slots_per_ms = mac->frame_structure.numb_slots_frame / 10; + ra->RA_backoff_limit = bi_ms * slots_per_ms; + LOG_I(NR_MAC, "[UE %d][RAPROC][RA-RNTI %04x] Got BI RAR subPDU %d ms\n", mac->ue_id, rnti, bi_ms); + if (((NR_RA_HEADER_BI *)rarh)->E == 1) { + rarh += sizeof(NR_RA_HEADER_BI); + continue; + } else { break; } - nr_ue_process_mac_pdu(mac, dl_info, pdu_id); + } + if (rarh->RAPID == preamble_index) { + // The MAC entity may stop ra-ResponseWindow (and hence monitoring for Random Access Response(s)) after + // successful reception of a Random Access Response containing Random Access Preamble identifiers + // that matches the transmitted PREAMBLE_INDEX. + nr_timer_stop(&ra->response_window_timer); + LOG_A(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mac->ue_id, frame, slot, rarh->RAPID); + rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); + handle_rar_reception(mac, rar, frame, slot); + if (ra->cfra) + nr_ra_succeeded(mac, dl_info->gNB_index, frame, slot); break; - case FAPI_NR_RX_PDU_TYPE_RAR : - nr_ue_process_rar(mac, dl_info, pdu_id); + } + if (rarh->E == 0) { + LOG_W(NR_MAC,"[UE %d][RAPROC][%d.%d] Received RAR preamble (%d) doesn't match the intended RAPID (%d)\n", + mac->ue_id, + frame, + slot, + rarh->RAPID, + preamble_index); + // resume RAR response window timer if MSG2 decoding failed + nr_timer_suspension(&mac->ra.response_window_timer); break; - default : - AssertFatal(false, "Invalid DLSCH PDU type\n"); + } else { + rarh += sizeof(NR_MAC_RAR) + 1; + } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); + +#ifdef DEBUG_RAR + LOG_D(NR_MAC, + "[DEBUG_RAR] (%d,%d) number of RAR subheader %d; number of RAR pyloads %d\n", + frame, + slot, + n_subheaders, + n_subPDUs); + LOG_D(NR_MAC, + "[DEBUG_RAR] Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", + *(uint8_t *) rarh, + rar[0], + rar[1], + rar[2], + rar[3], + rar[4], + rar[5], + rarh->RAPID, + preamble_index); +#endif + return; } // #define EXTRACT_DCI_ITEM(val,size) val= readBits(dci_pdu, &pos, size); @@ -3614,17 +3754,25 @@ static nr_dci_format_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, return format; } -static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, int frame, int slot) +nr_dci_format_t nr_ue_process_dci_indication_pdu(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) { - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment; - ul_time_alignment->ta_command = ta; - ul_time_alignment->ta_apply = type; - const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs); - const int n_slots_frame = mac->frame_structure.numb_slots_frame; - ul_time_alignment->frame = (frame + (slot + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER; - ul_time_alignment->slot = (slot + ntn_ue_koffset) % n_slots_frame; - // start or restart the timeAlignmentTimer associated with the indicated TAG - nr_timer_start(&mac->time_alignment_timer); + LOG_D(NR_MAC, + "Received dci indication (rnti %x, dci format %d, n_CCE %d, payloadSize %d, payload %llx)\n", + dci->rnti, + dci->dci_format, + dci->n_CCE, + dci->payloadSize, + *(unsigned long long *)dci->payloadBits); + const nr_dci_format_t format = + nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, dci->payloadBits, slot); + if (format == NR_DCI_NONE) + return NR_DCI_NONE; + int ret = nr_ue_process_dci(mac, frame, slot, mac->def_dci_pdu_rel15[slot] + format, dci, format); + if (ret < 0) { + mac->stats.bad_dci++; + return NR_DCI_NONE; + } + return format; } static bool check_ra_contention_resolution(const uint8_t *pdu, const uint8_t *cont_res) @@ -4054,240 +4202,36 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, return mac_ce - pdu; } -static void handle_rar_reception(NR_UE_MAC_INST_t *mac, NR_MAC_RAR *rar, frame_t frame, int slot) +void nr_ue_send_sdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id) { - RAR_grant_t rar_grant; - RA_config_t *ra = &mac->ra; -#ifdef DEBUG_RAR - // CSI - unsigned char csi_req = (unsigned char)(rar->UL_GRANT_4 & 0x01); -#endif + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); - // TPC - unsigned char tpc_command = (unsigned char)((rar->UL_GRANT_4 >> 1) & 0x07); - ra->Msg3_TPC = (tpc_command << 1) - 6; + LOG_D(NR_MAC, + "In [%d.%d] Handling DLSCH PDU type %d\n", + dl_info->frame, + dl_info->slot, + dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type); - // MCS - rar_grant.mcs = (unsigned char)(rar->UL_GRANT_4 >> 4); - // time alloc - rar_grant.Msg3_t_alloc = (unsigned char)(rar->UL_GRANT_3 & 0x0f); - // frequency alloc - rar_grant.Msg3_f_alloc = (uint16_t)((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12)); - // frequency hopping - rar_grant.freq_hopping = (unsigned char)(rar->UL_GRANT_1 >> 2); - - // Schedule Msg3 - const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; - const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; - const NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[current_DL_BWP->bwp_id]; - const NR_SearchSpace_t *ra_SS = get_common_search_space(mac, pdcch_config->ra_SS_id); - NR_tda_info_t tda_info = get_ul_tda_info(current_UL_BWP, - *ra_SS->controlResourceSetId, - ra_SS->searchSpaceType->present, - TYPE_RA_RNTI_, - rar_grant.Msg3_t_alloc); - if (!tda_info.valid_tda || tda_info.nrOfSymbols == 0) { - LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n"); - // resume RAR response window timer if MSG2 decoding failed - nr_timer_suspension(&mac->ra.response_window_timer); - return; - } - frame_t frame_tx = 0; - int slot_tx = 0; - const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs); - int ret = nr_ue_pusch_scheduler(mac, 1, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset); - - // TA command - // if the timeAlignmentTimer associated with this TAG is not running - if (!nr_timer_is_active(&mac->time_alignment_timer)) { - const int ta = rar->TA2 + (rar->TA1 << 5); - set_time_alignment(mac, ta, rar_ta, frame_tx, slot_tx); - LOG_W(MAC, "received TA command %d\n", 31 + ta); - } - // else ignore the received Timing Advance Command - -#ifdef DEBUG_RAR - LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E); - LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T); - LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID); - - LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R); - LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1); - - LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2); - LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1); - - LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2); - LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3); - LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4); - - LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1); - LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2); - - LOG_I(NR_MAC, - "[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d\n", - frame, - slot, - mac->ue_id, - rar_grant.Msg3_t_alloc, - rar_grant.Msg3_f_alloc, - ta_command, - rar_grant.mcs, - rar_grant.freq_hopping, - tpc_command); -#endif - - if (ret != -1) { - uint16_t rnti = mac->crnti; - // Upon successful reception, set the T-CRNTI to the RAR value - // if the RA preamble is selected among the contention-based RA Preambles - if (!ra->cfra) { - ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); - rnti = ra->t_crnti; - if (!mac->msg3_C_RNTI) - nr_mac_rrc_msg3_ind(mac->ue_id, rnti, false); - } - fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); - if (!pdu) - return; - // Config Msg3 PDU - int ret = nr_config_pusch_pdu(mac, - &tda_info, - &pdu->pusch_config_pdu, - NULL, - NULL, - &rar_grant, - rnti, - NR_SearchSpace__searchSpaceType_PR_common, - NR_DCI_NONE); - if (ret != 0) - remove_ul_config_last_item(pdu); - release_ul_config(pdu, false); - } -} - -///////////////////////////////////// -// Random Access Response PDU // -// TS 38.213 ch 8.2 // -// TS 38.321 ch 6.2.3 // -///////////////////////////////////// -//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise -//| E | T | R A P I D |// -//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// -//| R | T A |// -//| T A | UL grant |// -//| UL grant |// -//| UL grant |// -//| UL grant |// -//| T C - R N T I |// -//| T C - R N T I |// -///////////////////////////////////// -// UL grant (27 bits) // -///////////////////////////////////// -//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise -//|-------------------|FHF|F_alloc|// -//| Freq allocation |// -//| F_alloc |Time allocation|// -//| MCS | TPC |CSI|// -///////////////////////////////////// -// TbD WIP Msg3 development ongoing -// - apply UL grant freq alloc & time alloc as per 8.2 TS 38.213 -// - apply tpc command -// WIP fix: -// - time domain indication hardcoded to 0 for k2 offset -// - extend TS 38.213 ch 8.3 Msg3 PUSCH -// - b buffer -// - ulsch power offset -// - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures -static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, int pdu_id) -{ - frame_t frame = dl_info->frame; - int slot = dl_info->slot; - - if(dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack == 0) { - LOG_W(NR_MAC,"[UE %d][RAPROC][%d.%d] CRC check failed on RAR (NAK)\n", mac->ue_id, frame, slot); - return; - } - - RA_config_t *ra = &mac->ra; - ra->t_crnti = 0; - uint8_t n_subPDUs = 0; // number of RAR payloads - uint8_t n_subheaders = 0; // number of MAC RAR subheaders - uint8_t *dlsch_buffer = dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.pdu; - NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer - NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer - uint8_t preamble_index = ra->ra_PreambleIndex; - uint16_t rnti = mac->ra.ra_rnti; - - T(T_NRUE_MAC_DL_RAR_PDU_WITH_DATA, T_INT(rnti), T_INT(frame), T_INT(slot), - T_BUFFER(dlsch_buffer, dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.pdu_length)); - - ra->RA_backoff_limit = 0; - LOG_D(NR_MAC, "[%d.%d]: [UE %d][RAPROC] MAC received RAR (current preamble %d)\n", frame, slot, mac->ue_id, preamble_index); - - while (1) { - n_subheaders++; - if (rarh->T == 1) { - n_subPDUs++; - LOG_I(NR_MAC, "[UE %d][RAPROC][RA-RNTI %04x] Got RAPID RAR subPDU\n", mac->ue_id, rnti); - } else { - int bi_ms = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI] * ra->scaling_factor_bi; - int slots_per_ms = mac->frame_structure.numb_slots_frame / 10; - ra->RA_backoff_limit = bi_ms * slots_per_ms; - LOG_I(NR_MAC, "[UE %d][RAPROC][RA-RNTI %04x] Got BI RAR subPDU %d ms\n", mac->ue_id, rnti, bi_ms); - if (((NR_RA_HEADER_BI *)rarh)->E == 1) { - rarh += sizeof(NR_RA_HEADER_BI); - continue; - } else { + // Processing MAC PDU + // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs + switch (dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type) { + case FAPI_NR_RX_PDU_TYPE_DLSCH : + // start or restart dataInactivityTimer if any MAC entity receives a MAC SDU for DTCH logical channel, + // DCCH logical channel, or CCCH logical channel + if (mac->data_inactivity_timer) + nr_timer_start(mac->data_inactivity_timer); + // DL data arrival during RRC_CONNECTED when UL synchronisation status is "non-synchronised" + if (!nr_timer_is_active(&mac->time_alignment_timer) && mac->state == UE_CONNECTED && !get_softmodem_params()->phy_test) { + trigger_MAC_UE_RA(mac, NULL); break; } - } - if (rarh->RAPID == preamble_index) { - // The MAC entity may stop ra-ResponseWindow (and hence monitoring for Random Access Response(s)) after - // successful reception of a Random Access Response containing Random Access Preamble identifiers - // that matches the transmitted PREAMBLE_INDEX. - nr_timer_stop(&ra->response_window_timer); - LOG_A(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mac->ue_id, frame, slot, rarh->RAPID); - rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); - handle_rar_reception(mac, rar, frame, slot); - if (ra->cfra) - nr_ra_succeeded(mac, dl_info->gNB_index, frame, slot); + nr_ue_process_mac_pdu(mac, dl_info, pdu_id); break; - } - if (rarh->E == 0) { - LOG_W(NR_MAC,"[UE %d][RAPROC][%d.%d] Received RAR preamble (%d) doesn't match the intended RAPID (%d)\n", - mac->ue_id, - frame, - slot, - rarh->RAPID, - preamble_index); - // resume RAR response window timer if MSG2 decoding failed - nr_timer_suspension(&mac->ra.response_window_timer); + case FAPI_NR_RX_PDU_TYPE_RAR : + nr_ue_process_rar(mac, dl_info, pdu_id); break; - } else { - rarh += sizeof(NR_MAC_RAR) + 1; - } + default : + AssertFatal(false, "Invalid DLSCH PDU type\n"); } - -#ifdef DEBUG_RAR - LOG_D(NR_MAC, - "[DEBUG_RAR] (%d,%d) number of RAR subheader %d; number of RAR pyloads %d\n", - frame, - slot, - n_subheaders, - n_subPDUs); - LOG_D(NR_MAC, - "[DEBUG_RAR] Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", - *(uint8_t *) rarh, - rar[0], - rar[1], - rar[2], - rar[3], - rar[4], - rar[5], - rarh->RAPID, - preamble_index); -#endif - return; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); } - diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index bd9ea09041..2818c20c37 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -57,31 +57,6 @@ AssertFatal(ret == 0, "Failure in mutex management ret=%d\n", a); \ } -static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP); -static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac); -static void schedule_ntn_config_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac); - -static void nr_ue_fill_phr(NR_UE_MAC_INST_t *mac, - NR_SINGLE_ENTRY_PHR_MAC_CE *phr, - float P_CMAX, - float tx_power, - frame_t frame, - slot_t slot); -static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, - int cc_id, - frame_t frame, - slot_t slot, - uint8_t gNB_index, - uint8_t *ulsch_buffer, - const uint32_t buflen, - int tx_power, - int P_MAX, - bool *BSRsent); - -static void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP); -static void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot); -static void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot); - static void clear_ul_config_request(NR_UE_MAC_INST_t *mac) { int slots = mac->frame_structure.numb_slots_frame; @@ -586,11 +561,10 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, pusch_config_pdu->pusch_uci.harq_ack_bit_length = 0; + pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart; if (dci_format == NR_UL_DCI_FORMAT_0_0 && ss_type == NR_SearchSpace__searchSpaceType_PR_common) { - pusch_config_pdu->bwp_start = sc_info->initial_ul_BWPStart; pusch_config_pdu->bwp_size = sc_info->initial_ul_BWPSize; } else { - pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart; pusch_config_pdu->bwp_size = current_UL_BWP->BWPSize; } @@ -1057,10 +1031,10 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger } int scs = mac->current_UL_BWP->scs; - AssertFatal(slot_offset > GET_DURATION_RX_TO_TX(&mac->ntn_ta, scs), + AssertFatal(slot_offset > GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, scs), "Slot offset between DCI and aperiodic SRS (%d) needs to be higher than DURATION_RX_TO_TX (%ld)\n", slot_offset, - GET_DURATION_RX_TO_TX(&mac->ntn_ta, scs)); + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, scs)); int n_slots_frame = mac->frame_structure.numb_slots_frame; int sched_slot = (slot + slot_offset) % n_slots_frame; if (!is_ul_slot(sched_slot, &mac->frame_structure)) { @@ -1133,6 +1107,205 @@ static bool nr_ue_periodic_srs_scheduling(NR_UE_MAC_INST_t *mac, frame_t frame, return srs_scheduled; } +static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac) +{ + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment; + fapi_nr_ta_command_pdu *ta = &dl_config->dl_config_list[dl_config->number_pdus].ta_command_pdu; + ta->ta_frame = ul_time_alignment->frame; + ta->ta_slot = ul_time_alignment->slot; + ta->is_rar = ul_time_alignment->ta_apply == rar_ta; + ta->ta_command = ul_time_alignment->ta_command; + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_CONFIG_TA_COMMAND; + dl_config->number_pdus += 1; + ul_time_alignment->ta_apply = no_ta; +} + +static NR_CSI_ResourceConfigId_t find_CSI_resourceconfig(NR_CSI_MeasConfig_t *csi_measconfig, + NR_BWP_Id_t dl_bwp_id, + NR_NZP_CSI_RS_ResourceId_t csi_id) +{ + bool found = false; + for (int csi_list = 0; csi_list < csi_measconfig->csi_ResourceConfigToAddModList->list.count; csi_list++) { + NR_CSI_ResourceConfig_t *csires = csi_measconfig->csi_ResourceConfigToAddModList->list.array[csi_list]; + if(csires->bwp_Id != dl_bwp_id) + continue; + struct NR_CSI_ResourceConfig__csi_RS_ResourceSetList *resset = &csires->csi_RS_ResourceSetList; + if(resset->present != NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB) + continue; + if(!resset->choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) + continue; + for(int i = 0; i < resset->choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.count; i++) { + NR_NZP_CSI_RS_ResourceSetId_t *res_id = resset->choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[i]; + AssertFatal(res_id, "NR_NZP_CSI_RS_ResourceSetId shouldn't be NULL\n"); + struct NR_CSI_MeasConfig__nzp_CSI_RS_ResourceSetToAddModList *res_list = csi_measconfig->nzp_CSI_RS_ResourceSetToAddModList; + AssertFatal(res_list, "nzp_CSI_RS_ResourceSetToAddModList shouldn't be NULL\n"); + for (int j = 0; j < res_list->list.count; j++) { + NR_NZP_CSI_RS_ResourceSet_t *csi_res = res_list->list.array[j]; + if (*res_id != csi_res->nzp_CSI_ResourceSetId) + continue; + for (int k = 0; k < csi_res->nzp_CSI_RS_Resources.list.count; k++) { + AssertFatal(csi_res->nzp_CSI_RS_Resources.list.array[k], "NZP_CSI_RS_ResourceId shoulan't be NULL\n"); + if (csi_id == *csi_res->nzp_CSI_RS_Resources.list.array[k]) { + found = true; + break; + } + } + if (found && csi_res->trs_Info) + // CRI-RS for Tracking (not implemented yet) + // in this case we there is no associated CSI report + // therefore to signal this we return a value higher than + // maxNrofCSI-ResourceConfigurations + return NR_maxNrofCSI_ResourceConfigurations + 1; + else if (found) + return csires->csi_ResourceConfigId; + } + } + } + return -1; // not found any CSI-resource in current DL BWP associated with this CSI-RS ID +} + +static uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig, NR_CSI_ResourceConfigId_t csi_res_id) +{ + uint8_t meas_bitmap = 0; + if (csi_res_id > NR_maxNrofCSI_ResourceConfigurations) + return meas_bitmap; // CSI-RS for tracking + for(int i = 0; i < csi_measconfig->csi_ReportConfigToAddModList->list.count; i++) { + NR_CSI_ReportConfig_t *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[i]; + if(report_config->resourcesForChannelMeasurement != csi_res_id) + continue; + // bit 0 RSRP bit 1 RI bit 2 LI bit 3 PMI bit 4 CQI bit 5 i1 + switch (report_config->reportQuantity.present) { + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: + meas_bitmap += (1 << 1) + (1 << 3) + (1 << 4); + break; + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1: + meas_bitmap += (1 << 1) + (1 << 5); + break; + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI: + meas_bitmap += (1 << 1) + (1 << 4) + (1 << 5); + break; + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: + meas_bitmap += (1 << 1) + (1 << 4); + break; + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: + meas_bitmap += 1; + break; + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI: + meas_bitmap += (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4); + break; + default: + AssertFatal(false, "Unexpected measurement report type %d\n", report_config->reportQuantity.present); + } + } + return meas_bitmap; +} + +static void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) +{ + if (!mac->sc_info.csi_MeasConfig) + return; + + NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig; + + if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList == NULL) + return; + + fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); + NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; + NR_BWP_Id_t dl_bwp_id = current_DL_BWP->bwp_id; + + int mu = current_DL_BWP->scs; + uint16_t bwp_size = current_DL_BWP->BWPSize; + uint16_t bwp_start = current_DL_BWP->BWPStart; + + for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++) { + NR_NZP_CSI_RS_Resource_t *nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id]; + int period, offset; + csi_period_offset(NULL, nzpcsi->periodicityAndOffset, &period, &offset); + if((frame * mac->frame_structure.numb_slots_frame + slot-offset) % period != 0) + continue; + NR_CSI_ResourceConfigId_t csi_res_id = find_CSI_resourceconfig(csi_measconfig, dl_bwp_id, nzpcsi->nzp_CSI_RS_ResourceId); + // do not schedule reseption of this CSI-RS if not associated with current BWP + if(csi_res_id < 0) + continue; + LOG_D(MAC,"Scheduling reception of CSI-RS in frame %d slot %d\n", frame, slot); + fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].csirs_config_pdu.csirs_config_rel15; + csirs_config_pdu->measurement_bitmap = set_csirs_measurement_bitmap(csi_measconfig, csi_res_id); + csirs_config_pdu->subcarrier_spacing = mu; + csirs_config_pdu->cyclic_prefix = current_DL_BWP->cyclicprefix ? *current_DL_BWP->cyclicprefix : 0; + + if (csi_res_id > NR_maxNrofCSI_ResourceConfigurations) + csirs_config_pdu->csi_type = 0; // TRS + else + csirs_config_pdu->csi_type = 1; // NZP-CSI-RS + + csirs_config_pdu->scramb_id = nzpcsi->scramblingID; + csirs_config_pdu->power_control_offset = nzpcsi->powerControlOffset + 8; + if (nzpcsi->powerControlOffsetSS) + csirs_config_pdu->power_control_offset_ss = *nzpcsi->powerControlOffsetSS; + else + csirs_config_pdu->power_control_offset_ss = 1; // 0 dB + + configure_csi_resource_mapping(csirs_config_pdu, &nzpcsi->resourceMapping, bwp_size, bwp_start); + + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_RS; + dl_config->number_pdus += 1; + } +} + +static void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) +{ + if (!mac->sc_info.csi_MeasConfig) + return; + + NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig; + + if (csi_measconfig->csi_IM_ResourceToAddModList == NULL) + return; + + fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); + NR_CSI_IM_Resource_t *imcsi; + int period, offset; + + NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; + int mu = current_DL_BWP->scs; + uint16_t bwp_size = current_DL_BWP->BWPSize; + uint16_t bwp_start = current_DL_BWP->BWPStart; + + for (int id = 0; id < csi_measconfig->csi_IM_ResourceToAddModList->list.count; id++){ + imcsi = csi_measconfig->csi_IM_ResourceToAddModList->list.array[id]; + csi_period_offset(NULL,imcsi->periodicityAndOffset,&period,&offset); + if((frame * mac->frame_structure.numb_slots_frame + slot - offset ) %period != 0) + continue; + fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].csiim_config_pdu.csiim_config_rel15; + csiim_config_pdu->bwp_size = bwp_size; + csiim_config_pdu->bwp_start = bwp_start; + csiim_config_pdu->subcarrier_spacing = mu; + csiim_config_pdu->start_rb = imcsi->freqBand->startingRB; + csiim_config_pdu->nr_of_rbs = imcsi->freqBand->nrofRBs; + // As specified in 5.2.2.4 of 38.214 + switch (imcsi->csi_IM_ResourceElementPattern->present) { + case NR_CSI_IM_Resource__csi_IM_ResourceElementPattern_PR_pattern0: + for (int i = 0; i < 4; i++) { + csiim_config_pdu->k_csiim[i] = + (imcsi->csi_IM_ResourceElementPattern->choice.pattern0->subcarrierLocation_p0 << 1) + (i >> 1); + csiim_config_pdu->l_csiim[i] = imcsi->csi_IM_ResourceElementPattern->choice.pattern0->symbolLocation_p0 + (i % 2); + } + break; + case NR_CSI_IM_Resource__csi_IM_ResourceElementPattern_PR_pattern1: + for (int i = 0; i < 4; i++) { + csiim_config_pdu->k_csiim[i] = (imcsi->csi_IM_ResourceElementPattern->choice.pattern1->subcarrierLocation_p1 << 2) + i; + csiim_config_pdu->l_csiim[i] = imcsi->csi_IM_ResourceElementPattern->choice.pattern1->symbolLocation_p1; + } + break; + default: + AssertFatal(1 == 0, "Invalid CSI-IM pattern\n"); + } + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_IM; + dl_config->number_pdus += 1; + } +} + // Performs : // 1. TODO: Call RRC for link status return to PHY // 2. TODO: Perform SR/BSR procedures for scheduling feedback @@ -1146,7 +1319,7 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info dl_config->slot = rx_slot; dl_config->number_pdus = 0; - if (mac->state == UE_NOT_SYNC || mac->state == UE_DETACHING) + if (mac->state == UE_NOT_SYNC || mac->state == UE_NOT_SYNC_RECONF || mac->state == UE_DETACHING) return; if (mac->state == UE_CONNECTED) { @@ -1158,11 +1331,6 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info if (mac->ul_time_alignment.ta_apply != no_ta) schedule_ta_command(dl_config, mac); - - if (mac->ntn_ta.ntn_params_changed) { - mac->ntn_ta.ntn_params_changed = false; - schedule_ntn_config_command(dl_config, mac); - } nr_scheduled_response_t scheduled_response = {.dl_config = dl_config, .module_id = mac->ue_id, @@ -1348,260 +1516,179 @@ static void nr_update_bsr(NR_UE_MAC_INST_t *mac, uint32_t *LCG_bytes) } } -void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) +static bool is_prach_frame(frame_t frame, prach_occasion_info_t *prach_occasion_info, int association_periods) { - int cc_id = ul_info->cc_id; - frame_t frame_tx = ul_info->frame; - slot_t slot_tx = ul_info->slot; - uint32_t gNB_index = ul_info->gNB_index; + int config_period = prach_occasion_info->frame_info[0]; + int frame_period = config_period * association_periods; + int frame_in_period = frame % frame_period; + if (association_periods > 1) { + int current_assoc_period = frame_in_period / config_period; + if (current_assoc_period != prach_occasion_info->association_period_idx) + return false; + frame_in_period %= config_period; + } + if (frame_in_period == prach_occasion_info->frame_info[1]) // SFN % x == y (see Tables in Table 6.3.3.2 of 38.211) + return true; + else + return false; +} +// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x +// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3. +// - todo: +// - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config +static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP) +{ RA_config_t *ra = &mac->ra; - if (mac->state == UE_PERFORMING_RA && ra->ra_state == nrRA_UE_IDLE) { - init_RA(mac, frame_tx); - // perform the Random Access Resource selection procedure (see clause 5.1.2 and .2a) - ra_resource_selection(mac); - } + // Get any valid PRACH occasion in the current slot for the selected SSB index + prach_occasion_info_t *prach_occasion_info = &ra->sched_ro_info; - if (mac->state == UE_PERFORMING_RA && ra->ra_state == nrRA_GENERATE_PREAMBLE) - nr_ue_prach_scheduler(mac, frame_tx, slot_tx); - - bool BSRsent = false; - if (mac->state == UE_CONNECTED) { - nr_ue_periodic_srs_scheduling(mac, frame_tx, slot_tx); - nr_update_rlc_buffers_status(mac, frame_tx, slot_tx, gNB_index); - } - - // Schedule ULSCH only if the current frame and slot match those in ul_config_req - // AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus) - uint8_t ulsch_input_buffer_array[NFAPI_MAX_NUM_UL_PDU][MAX_ULSCH_PAYLOAD_BYTES]; - int number_of_pdus = 0; - - fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = lockGet_ul_iterator(mac, frame_tx, slot_tx); - if (!ulcfg_pdu) + if (!is_prach_frame(frameP, prach_occasion_info, ra->association_periods)) return; - LOG_D(NR_MAC, "number of UL PDUs: %d with UL transmission in sfn [%d.%d]\n", *ulcfg_pdu->privateNBpdus, frame_tx, slot_tx); - while (ulcfg_pdu->pdu_type != FAPI_NR_END) { - uint8_t *ulsch_input_buffer = ulsch_input_buffer_array[number_of_pdus]; - if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { - nfapi_nr_ue_pusch_pdu_t *pdu = &ulcfg_pdu->pusch_config_pdu; - uint32_t TBS_bytes = pdu->pusch_data.tb_size; - LOG_D(NR_MAC, - "harq_id %d, new_data_indicator %d, TBS_bytes %d (ra_state %d)\n", - pdu->pusch_data.harq_process_id, - pdu->pusch_data.new_data_indicator, - TBS_bytes, - ra->ra_state); - pdu->tx_request_body.fapiTxPdu = NULL; - if ((ra->ra_state == nrRA_WAIT_RAR || ra->ra_state == nrRA_WAIT_MSGB) && !ra->cfra) { - nr_get_Msg3_MsgA_PUSCH_payload(mac, ulsch_input_buffer, TBS_bytes); - for (int k = 0; k < TBS_bytes; k++) { - LOG_D(NR_MAC, "(%i): 0x%x\n", k, ulsch_input_buffer[k]); + if (is_ul_slot(slotP, &mac->frame_structure)) { + if (slotP == prach_occasion_info->slot) { + fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH); + if (!pdu) { + LOG_E(NR_MAC, "Error in PRACH allocation\n"); + return; + } + + int format = prach_occasion_info->format; + fapi_nr_prach_config_t *prach_config = &mac->phy_config.config_req.prach_config; + pdu->prach_config_pdu = (fapi_nr_ul_config_prach_pdu){ + .phys_cell_id = mac->physCellId, + .num_prach_ocas = 1, + .prach_slot = prach_occasion_info->slot, + .prach_start_symbol = prach_occasion_info->start_symbol, + .num_ra = prach_occasion_info->fdm, + .num_cs = get_NCS(ra->zeroCorrelationZoneConfig, format, ra->restricted_set_config), + .root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info->fdm].prach_root_sequence_index, + .restricted_set = prach_config->restricted_set_config, + .freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info->fdm].k1}; + + LOG_I(NR_MAC, + "PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", + frameP, + pdu->prach_config_pdu.prach_slot, + pdu->prach_config_pdu.prach_start_symbol, + pdu->prach_config_pdu.num_ra); + + switch (format) { // single PRACH format + case 0: + pdu->prach_config_pdu.prach_format = 0; + break; + case 1: + pdu->prach_config_pdu.prach_format = 1; + break; + case 2: + pdu->prach_config_pdu.prach_format = 2; + break; + case 3: + pdu->prach_config_pdu.prach_format = 3; + break; + case 0xa1: + pdu->prach_config_pdu.prach_format = 4; + break; + case 0xa2: + pdu->prach_config_pdu.prach_format = 5; + break; + case 0xa3: + pdu->prach_config_pdu.prach_format = 6; + break; + case 0xb1: + pdu->prach_config_pdu.prach_format = 7; + break; + case 0xb4: + pdu->prach_config_pdu.prach_format = 8; + break; + case 0xc0: + pdu->prach_config_pdu.prach_format = 9; + break; + case 0xc2: + pdu->prach_config_pdu.prach_format = 10; + break; + default: + AssertFatal(false, "Invalid PRACH format"); + } + + pdu->prach_config_pdu.ra_PreambleIndex = ra->ra_PreambleIndex; + pdu->prach_config_pdu.prach_tx_power = get_prach_tx_power(mac); + release_ul_config(pdu, false); + nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slotP, + .mac = mac, + .module_id = mac->ue_id, + .CC_id = 0 /*TBR fix*/}; + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) + mac->if_module->scheduled_response(&scheduled_response); + + T(T_UE_PHY_INITIATE_RA_PROCEDURE, T_INT(frameP), T_INT(pdu->prach_config_pdu.prach_slot), + T_INT(pdu->prach_config_pdu.ra_PreambleIndex), T_INT(pdu->prach_config_pdu.prach_tx_power)); + + const int n_slots_frame = mac->frame_structure.numb_slots_frame; + if (ra->ra_type == RA_4_STEP) { + ra->ra_state = nrRA_WAIT_RAR; + // we start to monitor DCI for RAR in the first valid occasion after transmitting RACH + // the response window timer should be started at that time + // but for processing reasons it is better to start it here and to add the slot difference + // that also takes into account the rx to tx slot offset + int next_slot = (slotP + 1) % n_slots_frame; + int next_frame = (frameP + (next_slot < slotP)) % MAX_FRAME_NUMBER; + int add_slots = 1; + NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[mac->current_DL_BWP->bwp_id]; + const NR_SearchSpace_t *ra_SS = get_common_search_space(mac, pdcch_config->ra_SS_id); + while (!is_dl_slot(next_slot, &mac->frame_structure) + || !is_ss_monitor_occasion(next_frame, next_slot, n_slots_frame, ra_SS)) { + int temp_slot = (next_slot + 1) % n_slots_frame; + next_frame = (next_frame + (temp_slot < next_slot)) % MAX_FRAME_NUMBER; + next_slot = temp_slot; + add_slots++; } - pdu->tx_request_body.fapiTxPdu = ulsch_input_buffer; - pdu->tx_request_body.pdu_length = TBS_bytes; - number_of_pdus++; - T(T_NRUE_MAC_UL_PDU_WITH_DATA, T_INT(mac->crnti), T_INT(frame_tx), T_INT(slot_tx), - T_INT(ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id), T_BUFFER(ulsch_input_buffer, TBS_bytes)); + add_slots += GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mac->current_DL_BWP->scs); + nr_timer_setup(&ra->response_window_timer, ra->response_window_setup_time + add_slots, 1); + nr_timer_start(&ra->response_window_timer); + } else if (ra->ra_type == RA_2_STEP) { + NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = + mac->current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16; + slot_t msgA_pusch_slot = (slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) % n_slots_frame; + frame_t msgA_pusch_frame = + (frameP + ((slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) / n_slots_frame)) % 1024; + + fapi_nr_ul_config_request_pdu_t *pdu = + lockGet_ul_config(mac, msgA_pusch_frame, msgA_pusch_slot, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + if (!pdu) + return; + + // Config Msg3/MsgA-PUSCH PDU + NR_tda_info_t tda_info = {0}; + AssertFatal(msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16, + "Only SLIV based on startSymbolAndLengthMsgA_PO_r16 implemented\n"); + + int ret = nr_config_pusch_pdu(mac, + &tda_info, + &pdu->pusch_config_pdu, + NULL, + NULL, + NULL, + mac->ra.ra_rnti, + NR_SearchSpace__searchSpaceType_PR_common, + NR_DCI_NONE); + + if (ret != 0) + remove_ul_config_last_item(pdu); + release_ul_config(pdu, false); + + LOG_D(NR_MAC, "ra->ra_state %s\n", nrra_ue_text[ra->ra_state]); + ra->ra_state = nrRA_WAIT_MSGB; + ra->t_crnti = 0; + mac->crnti = 0; + ra->ra_rnti = 0; } else { - if (ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator - && (mac->state == UE_CONNECTED || (ra->ra_state == nrRA_WAIT_RAR && ra->cfra))) { - if (!nr_timer_is_active(&mac->time_alignment_timer) && mac->state == UE_CONNECTED && !get_softmodem_params()->phy_test) { - // UL data arrival during RRC_CONNECTED when UL synchronisation status is "non-synchronised" - trigger_MAC_UE_RA(mac, NULL); - return; - } - // Getting IP traffic to be transmitted - int tx_power = pdu->tx_power; - int P_CMAX = nr_get_Pcmax(mac->p_Max, - mac->nr_band, - mac->frame_structure.frame_type, - mac->frequency_range, - mac->current_UL_BWP->channel_bandwidth, - pdu->qam_mod_order, - false, - mac->current_UL_BWP->scs, - mac->current_UL_BWP->BWPSize, - pdu->transform_precoding, - pdu->rb_size, - pdu->rb_start); - - nr_ue_get_sdu(mac, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes, tx_power, P_CMAX, &BSRsent); - pdu->tx_request_body.fapiTxPdu = ulsch_input_buffer; - pdu->tx_request_body.pdu_length = TBS_bytes; - number_of_pdus++; - T(T_NRUE_MAC_UL_PDU_WITH_DATA, T_INT(mac->crnti), T_INT(frame_tx), T_INT(slot_tx), - T_INT(ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id), T_BUFFER(ulsch_input_buffer, TBS_bytes)); - // start or restart dataInactivityTimer if any MAC entity transmits a MAC SDU for DTCH logical channel, - // or DCCH logical channel - if (mac->data_inactivity_timer) - nr_timer_start(mac->data_inactivity_timer); - } + AssertFatal(false, "RA type %d not implemented!\n", ra->ra_type); } - - if (ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION && !ra->cfra) { - LOG_I(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx); - // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 - // transmission - nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index); - } - if (ra->ra_state == nrRA_WAIT_RAR && !ra->cfra) { - LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); - nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index); - } - if (ra->ra_state == nrRA_WAIT_MSGB && !ra->cfra) { - LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-MsgA-PUSCH transmitted\n", frame_tx, slot_tx); - } - } - ulcfg_pdu++; - } - release_ul_config(ulcfg_pdu, false); - - if(mac->state >= UE_PERFORMING_RA && mac->state < UE_DETACHING) - nr_ue_pucch_scheduler(mac, frame_tx, slot_tx); - - if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL) { - LOG_D(NR_MAC, "3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx); - nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slot_tx, - .mac = mac, - .module_id = mac->ue_id, - .CC_id = cc_id, - .phy_data = ul_info->phy_data}; - mac->if_module->scheduled_response(&scheduled_response); - } - - if(mac->state == UE_CONNECTED) - nr_update_sr(mac, BSRsent); - // Global variables implicit logic - // far away, BSR_reporting_active is set - mac->scheduling_info.BSR_reporting_active = NR_BSR_TRIGGER_NONE; - - // update Bj for all active lcids before LCP procedure - if (mac->current_UL_BWP) { - LOG_D(NR_MAC, "%4d.%2d Logical Channel Prioritization\n", frame_tx, slot_tx); - for (int i = 0; i < mac->lc_ordered_list.count; i++) { - nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; - int lcid = lc_info->lcid; - // max amount of data that can be buffered/accumulated in a logical channel buffer - uint32_t bucketSize_max = lc_info->bucket_size; - // measure Bj increment the value of Bj by product PBR * T - NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid); - int32_t bj = sched_info->Bj; - if (lc_info->pbr < UINT_MAX) { - uint32_t slots_elapsed = nr_timer_elapsed_time(&sched_info->Bj_timer); // slots elapsed since Bj was last incremented - // it is safe to divide by 1k since pbr in lc_info is computed multiplying by 1000 the RRC value to convert kB/s to B/s - uint32_t pbr_ms = lc_info->pbr / 1000; - bj += ((pbr_ms * slots_elapsed) >> mac->current_UL_BWP->scs); // each slot length is 1/scs ms - } - else - bj = INT_MAX; - // bj > max bucket size, set bj to max bucket size, as in ts38.321 5.4.3.1 Logical Channel Prioritization - sched_info->Bj = min(bj, bucketSize_max); - // reset bj timer - nr_timer_start(&sched_info->Bj_timer); - } - } -} - -static uint8_t nr_locate_BsrIndexByBufferSize(int size, int value) -{ - if (value == 0) { - return 0; //elseif (value > 150000) return 63; - } - - uint32_t (*get_bsr_value)(int); - if (size == NR_SHORT_BSR_TABLE_SIZE) - get_bsr_value = &get_short_bsr_value; - else - get_bsr_value = &get_long_bsr_value; - - int jl = 0; // lower bound - int ju = size - 1; // upper bound - // determine the order of the the table: 1 if ascending order of table, 0 otherwise - bool ascend = (*get_bsr_value)(ju) >= (*get_bsr_value)(jl) ? 1 : 0; - while (ju - jl > 1) { //If we are not yet done, - int jm = (ju + jl) / 2; // compute a midpoint, - if ((value >= (*get_bsr_value)(jm)) == ascend) { - jl = jm; // replace the lower limit - } else { - ju = jm; //replace the upper limit - } - - LOG_T(NR_MAC, - "[UE] searching BSR index %d for (BSR TABLE %d < value %d)\n", - jm, - (*get_bsr_value)(jm), - value); - } - - if (value == (*get_bsr_value)(jl)) { - return jl; - } else { - return jl + 1; //equally ju - } -} - -// PUSCH scheduler: -// - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, -// - where K2 is the offset between the slot in which UL DCI is received and the slot -// - in which ULSCH should be scheduled. K2 is configured in RRC configuration. -// PUSCH Msg3 scheduler: -// - scheduled by RAR UL grant according to 8.3 of TS 38.213 -// Note: Msg3 tx in the uplink symbols of mixed slot -int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac, - const uint8_t is_Msg3, - const frame_t current_frame, - const int current_slot, - frame_t *frame_tx, - int *slot_tx, - const long k2) -{ - int delta = 0; - const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; - - // Get the numerology to calculate the Tx frame and slot - int mu = current_UL_BWP->scs; - int slots_per_frame = mac->frame_structure.numb_slots_frame; - - // k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1 - // PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon - - if (is_Msg3) { - - delta = get_delta_for_k2(mu); - - AssertFatal((k2 + delta) > GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu), - "Slot offset (%ld) for Msg3 needs to be higher than DURATION_RX_TO_TX (%ld). Please set min_rxtxtime at least to " - "%ld in gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n", - k2, - GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu), - GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu), - GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu)); - - *slot_tx = (current_slot + k2 + delta) % slots_per_frame; - *frame_tx = (current_frame + (current_slot + k2 + delta) / slots_per_frame) % MAX_FRAME_NUMBER; - } else { - AssertFatal(k2 >= GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu), - "Slot offset K2 (%ld) needs to be higher than DURATION_RX_TO_TX (%ld). Please set min_rxtxtime at least to %ld in " - "gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n", - k2, - GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu), - GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu), - GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu)); - - if (k2 < 0) { // This can happen when a false DCI is received - LOG_W(PHY, "%d.%d. Received k2 %ld\n", current_frame, current_slot, k2); - return -1; - } - - // Calculate TX slot and frame - *slot_tx = (current_slot + k2) % slots_per_frame; - *frame_tx = (current_frame + (current_slot + k2) / slots_per_frame) % MAX_FRAME_NUMBER; - } - - LOG_D(NR_MAC, "[%04d.%02d] UL transmission in [%04d.%02d] (k2 %ld delta %d)\n", current_frame, current_slot, *frame_tx, *slot_tx, k2, delta); - return 0; + } // is_nr_prach_slot + } // if is_nr_UL_slot } static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, @@ -1789,473 +1876,43 @@ static void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frame, int slot } } -static void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) +static void nr_ue_fill_phr(NR_UE_MAC_INST_t *mac, + NR_SINGLE_ENTRY_PHR_MAC_CE *phr, + float P_CMAX, + float tx_power, + frame_t frame, + slot_t slot) { - if (!mac->sc_info.csi_MeasConfig) - return; - - NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig; - - if (csi_measconfig->csi_IM_ResourceToAddModList == NULL) - return; - - fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); - NR_CSI_IM_Resource_t *imcsi; - int period, offset; - - NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; - int mu = current_DL_BWP->scs; - uint16_t bwp_size = current_DL_BWP->BWPSize; - uint16_t bwp_start = current_DL_BWP->BWPStart; - - for (int id = 0; id < csi_measconfig->csi_IM_ResourceToAddModList->list.count; id++){ - imcsi = csi_measconfig->csi_IM_ResourceToAddModList->list.array[id]; - csi_period_offset(NULL,imcsi->periodicityAndOffset,&period,&offset); - if((frame * mac->frame_structure.numb_slots_frame + slot - offset ) %period != 0) - continue; - fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].csiim_config_pdu.csiim_config_rel15; - csiim_config_pdu->bwp_size = bwp_size; - csiim_config_pdu->bwp_start = bwp_start; - csiim_config_pdu->subcarrier_spacing = mu; - csiim_config_pdu->start_rb = imcsi->freqBand->startingRB; - csiim_config_pdu->nr_of_rbs = imcsi->freqBand->nrofRBs; - // As specified in 5.2.2.4 of 38.214 - switch (imcsi->csi_IM_ResourceElementPattern->present) { - case NR_CSI_IM_Resource__csi_IM_ResourceElementPattern_PR_pattern0: - for (int i = 0; i < 4; i++) { - csiim_config_pdu->k_csiim[i] = - (imcsi->csi_IM_ResourceElementPattern->choice.pattern0->subcarrierLocation_p0 << 1) + (i >> 1); - csiim_config_pdu->l_csiim[i] = imcsi->csi_IM_ResourceElementPattern->choice.pattern0->symbolLocation_p0 + (i % 2); - } - break; - case NR_CSI_IM_Resource__csi_IM_ResourceElementPattern_PR_pattern1: - for (int i = 0; i < 4; i++) { - csiim_config_pdu->k_csiim[i] = (imcsi->csi_IM_ResourceElementPattern->choice.pattern1->subcarrierLocation_p1 << 2) + i; - csiim_config_pdu->l_csiim[i] = imcsi->csi_IM_ResourceElementPattern->choice.pattern1->symbolLocation_p1; - } - break; - default: - AssertFatal(1 == 0, "Invalid CSI-IM pattern\n"); - } - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_IM; - dl_config->number_pdus += 1; + nr_phr_info_t *phr_info = &mac->scheduling_info.phr_info; + // Value mapping according to 38.133 10.1.18.1 + const int PC_MAX_00 = -29; + *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE){.PCMAX = max(0, (int)P_CMAX - PC_MAX_00) & 0x3f}; + // Value mapping according to 38.133 10.1.17.1.1 + const int POWER_HEADROOM_55 = 22; + int headroom = P_CMAX - tx_power; + if (headroom < POWER_HEADROOM_55) { + const int POWER_HEADROOM_0 = -32; + phr->PH = max(0, headroom - POWER_HEADROOM_0); + } else { + phr->PH = min(0x3f, 55 + (headroom - POWER_HEADROOM_55) / 2); } -} -NR_CSI_ResourceConfigId_t find_CSI_resourceconfig(NR_CSI_MeasConfig_t *csi_measconfig, - NR_BWP_Id_t dl_bwp_id, - NR_NZP_CSI_RS_ResourceId_t csi_id) -{ - bool found = false; - for (int csi_list = 0; csi_list < csi_measconfig->csi_ResourceConfigToAddModList->list.count; csi_list++) { - NR_CSI_ResourceConfig_t *csires = csi_measconfig->csi_ResourceConfigToAddModList->list.array[csi_list]; - if(csires->bwp_Id != dl_bwp_id) - continue; - struct NR_CSI_ResourceConfig__csi_RS_ResourceSetList *resset = &csires->csi_RS_ResourceSetList; - if(resset->present != NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB) - continue; - if(!resset->choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) - continue; - for(int i = 0; i < resset->choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.count; i++) { - NR_NZP_CSI_RS_ResourceSetId_t *res_id = resset->choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[i]; - AssertFatal(res_id, "NR_NZP_CSI_RS_ResourceSetId shouldn't be NULL\n"); - struct NR_CSI_MeasConfig__nzp_CSI_RS_ResourceSetToAddModList *res_list = csi_measconfig->nzp_CSI_RS_ResourceSetToAddModList; - AssertFatal(res_list, "nzp_CSI_RS_ResourceSetToAddModList shouldn't be NULL\n"); - for (int j = 0; j < res_list->list.count; j++) { - NR_NZP_CSI_RS_ResourceSet_t *csi_res = res_list->list.array[j]; - if (*res_id != csi_res->nzp_CSI_ResourceSetId) - continue; - for (int k = 0; k < csi_res->nzp_CSI_RS_Resources.list.count; k++) { - AssertFatal(csi_res->nzp_CSI_RS_Resources.list.array[k], "NZP_CSI_RS_ResourceId shoulan't be NULL\n"); - if (csi_id == *csi_res->nzp_CSI_RS_Resources.list.array[k]) { - found = true; - break; - } - } - if (found && csi_res->trs_Info) - // CRI-RS for Tracking (not implemented yet) - // in this case we there is no associated CSI report - // therefore to signal this we return a value higher than - // maxNrofCSI-ResourceConfigurations - return NR_maxNrofCSI_ResourceConfigurations + 1; - else if (found) - return csires->csi_ResourceConfigId; - } - } - } - return -1; // not found any CSI-resource in current DL BWP associated with this CSI-RS ID -} + LOG_D(NR_MAC, + "PHR Reporting sfn.slot %d.%d reason = %d, P_CMAX = %d (%5.2f dBm), headrom = %d (%d dB) tx_power = %5.2f dBm\n", + frame, + slot, + phr_info->phr_reporting, + phr->PCMAX, + P_CMAX, + phr->PH, + headroom, + tx_power); -uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig, NR_CSI_ResourceConfigId_t csi_res_id) -{ - uint8_t meas_bitmap = 0; - if (csi_res_id > NR_maxNrofCSI_ResourceConfigurations) - return meas_bitmap; // CSI-RS for tracking - for(int i = 0; i < csi_measconfig->csi_ReportConfigToAddModList->list.count; i++) { - NR_CSI_ReportConfig_t *report_config = csi_measconfig->csi_ReportConfigToAddModList->list.array[i]; - if(report_config->resourcesForChannelMeasurement != csi_res_id) - continue; - // bit 0 RSRP bit 1 RI bit 2 LI bit 3 PMI bit 4 CQI bit 5 i1 - switch (report_config->reportQuantity.present) { - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: - meas_bitmap += (1 << 1) + (1 << 3) + (1 << 4); - break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1: - meas_bitmap += (1 << 1) + (1 << 5); - break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI: - meas_bitmap += (1 << 1) + (1 << 4) + (1 << 5); - break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: - meas_bitmap += (1 << 1) + (1 << 4); - break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: - meas_bitmap += 1; - break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI: - meas_bitmap += (1 << 1) + (1 << 2) + (1 << 3) + (1 << 4); - break; - default: - AssertFatal(false, "Unexpected measurement report type %d\n", report_config->reportQuantity.present); - } - } - return meas_bitmap; -} - -void configure_csi_resource_mapping(fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, - const NR_CSI_RS_ResourceMapping_t *resourceMapping, - uint32_t bwp_size, - uint32_t bwp_start) -{ - // According to last paragraph of TS 38.214 5.2.2.3.1 - if (resourceMapping->freqBand.startingRB < bwp_start) - csirs_config_pdu->start_rb = bwp_start; - else - csirs_config_pdu->start_rb = resourceMapping->freqBand.startingRB; - if (resourceMapping->freqBand.nrofRBs > (bwp_start + bwp_size - csirs_config_pdu->start_rb)) - csirs_config_pdu->nr_of_rbs = bwp_start + bwp_size - csirs_config_pdu->start_rb; - else - csirs_config_pdu->nr_of_rbs = resourceMapping->freqBand.nrofRBs; - AssertFatal(csirs_config_pdu->nr_of_rbs >= 24, "CSI-RS has %d RBs, but the minimum is 24\n", csirs_config_pdu->nr_of_rbs); - - csirs_config_pdu->symb_l0 = resourceMapping->firstOFDMSymbolInTimeDomain; - if (resourceMapping->firstOFDMSymbolInTimeDomain2) - csirs_config_pdu->symb_l1 = *resourceMapping->firstOFDMSymbolInTimeDomain2; - csirs_config_pdu->cdm_type = resourceMapping->cdm_Type; - - csirs_config_pdu->freq_density = resourceMapping->density.present; - if ((resourceMapping->density.present == NR_CSI_RS_ResourceMapping__density_PR_dot5) - && (resourceMapping->density.choice.dot5 == NR_CSI_RS_ResourceMapping__density__dot5_evenPRBs)) - csirs_config_pdu->freq_density--; - - switch(resourceMapping->frequencyDomainAllocation.present){ - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1: - csirs_config_pdu->row = 1; - csirs_config_pdu->freq_domain = ((resourceMapping->frequencyDomainAllocation.choice.row1.buf[0]) >> 4) & 0x0f; - break; - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2: - csirs_config_pdu->row = 2; - csirs_config_pdu->freq_domain = (((resourceMapping->frequencyDomainAllocation.choice.row2.buf[1] >> 4) & 0x0f) - | ((resourceMapping->frequencyDomainAllocation.choice.row2.buf[0] << 4) & 0xff0)); - break; - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4: - csirs_config_pdu->row = 4; - csirs_config_pdu->freq_domain = ((resourceMapping->frequencyDomainAllocation.choice.row4.buf[0]) >> 5) & 0x07; - break; - case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other: - csirs_config_pdu->freq_domain = ((resourceMapping->frequencyDomainAllocation.choice.other.buf[0]) >> 2) & 0x3f; - // determining the row of table 7.4.1.5.3-1 in 38.211 - switch (resourceMapping->nrofPorts) { - case NR_CSI_RS_ResourceMapping__nrofPorts_p1: - AssertFatal(1 == 0, "Resource with 1 CSI port shouldn't be within other rows\n"); - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p2: - csirs_config_pdu->row = 3; - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p4: - csirs_config_pdu->row = 5; - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p8: - if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) - csirs_config_pdu->row = 8; - else { - int num_k = 0; - for (int k = 0; k < 6; k++) - num_k += (((csirs_config_pdu->freq_domain) >> k) & 0x01); - if (num_k == 4) - csirs_config_pdu->row = 6; - else - csirs_config_pdu->row = 7; - } - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p12: - if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) - csirs_config_pdu->row = 10; - else - csirs_config_pdu->row = 9; - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p16: - if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) - csirs_config_pdu->row = 12; - else - csirs_config_pdu->row = 11; - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p24: - if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) - csirs_config_pdu->row = 14; - else { - if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) - csirs_config_pdu->row = 15; - else - csirs_config_pdu->row = 13; - } - break; - case NR_CSI_RS_ResourceMapping__nrofPorts_p32: - if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) - csirs_config_pdu->row = 17; - else { - if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) - csirs_config_pdu->row = 18; - else - csirs_config_pdu->row = 16; - } - break; - default: - AssertFatal(false, "Invalid number of ports in CSI-RS resource\n"); - } - break; - default: - AssertFatal(false, "Invalid freqency domain allocation in CSI-RS resource\n"); - } -} - -static void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) -{ - if (!mac->sc_info.csi_MeasConfig) - return; - - NR_CSI_MeasConfig_t *csi_measconfig = mac->sc_info.csi_MeasConfig; - - if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList == NULL) - return; - - fapi_nr_dl_config_request_t *dl_config = get_dl_config_request(mac, slot); - NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; - NR_BWP_Id_t dl_bwp_id = current_DL_BWP->bwp_id; - - int mu = current_DL_BWP->scs; - uint16_t bwp_size = current_DL_BWP->BWPSize; - uint16_t bwp_start = current_DL_BWP->BWPStart; - - for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++) { - NR_NZP_CSI_RS_Resource_t *nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id]; - int period, offset; - csi_period_offset(NULL, nzpcsi->periodicityAndOffset, &period, &offset); - if((frame * mac->frame_structure.numb_slots_frame + slot-offset) % period != 0) - continue; - NR_CSI_ResourceConfigId_t csi_res_id = find_CSI_resourceconfig(csi_measconfig, dl_bwp_id, nzpcsi->nzp_CSI_RS_ResourceId); - // do not schedule reseption of this CSI-RS if not associated with current BWP - if(csi_res_id < 0) - continue; - LOG_D(MAC,"Scheduling reception of CSI-RS in frame %d slot %d\n", frame, slot); - fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].csirs_config_pdu.csirs_config_rel15; - csirs_config_pdu->measurement_bitmap = set_csirs_measurement_bitmap(csi_measconfig, csi_res_id); - csirs_config_pdu->subcarrier_spacing = mu; - csirs_config_pdu->cyclic_prefix = current_DL_BWP->cyclicprefix ? *current_DL_BWP->cyclicprefix : 0; - - if (csi_res_id > NR_maxNrofCSI_ResourceConfigurations) - csirs_config_pdu->csi_type = 0; // TRS - else - csirs_config_pdu->csi_type = 1; // NZP-CSI-RS - - csirs_config_pdu->scramb_id = nzpcsi->scramblingID; - csirs_config_pdu->power_control_offset = nzpcsi->powerControlOffset + 8; - if (nzpcsi->powerControlOffsetSS) - csirs_config_pdu->power_control_offset_ss = *nzpcsi->powerControlOffsetSS; - else - csirs_config_pdu->power_control_offset_ss = 1; // 0 dB - - configure_csi_resource_mapping(csirs_config_pdu, &nzpcsi->resourceMapping, bwp_size, bwp_start); - - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_RS; - dl_config->number_pdus += 1; - } -} - -static bool is_prach_frame(frame_t frame, prach_occasion_info_t *prach_occasion_info, int association_periods) -{ - int config_period = prach_occasion_info->frame_info[0]; - int frame_period = config_period * association_periods; - int frame_in_period = frame % frame_period; - if (association_periods > 1) { - int current_assoc_period = frame_in_period / config_period; - if (current_assoc_period != prach_occasion_info->association_period_idx) - return false; - frame_in_period %= config_period; - } - if (frame_in_period == prach_occasion_info->frame_info[1]) // SFN % x == y (see Tables in Table 6.3.3.2 of 38.211) - return true; - else - return false; -} - -// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x -// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3. -// - todo: -// - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config -static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP) -{ - RA_config_t *ra = &mac->ra; - - // Get any valid PRACH occasion in the current slot for the selected SSB index - prach_occasion_info_t *prach_occasion_info = &ra->sched_ro_info; - - if (!is_prach_frame(frameP, prach_occasion_info, ra->association_periods)) - return; - - if (is_ul_slot(slotP, &mac->frame_structure)) { - if (slotP == prach_occasion_info->slot) { - fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH); - if (!pdu) { - LOG_E(NR_MAC, "Error in PRACH allocation\n"); - return; - } - - int format = prach_occasion_info->format; - fapi_nr_prach_config_t *prach_config = &mac->phy_config.config_req.prach_config; - pdu->prach_config_pdu = (fapi_nr_ul_config_prach_pdu){ - .phys_cell_id = mac->physCellId, - .num_prach_ocas = 1, - .prach_slot = prach_occasion_info->slot, - .prach_start_symbol = prach_occasion_info->start_symbol, - .num_ra = prach_occasion_info->fdm, - .num_cs = get_NCS(ra->zeroCorrelationZoneConfig, format, ra->restricted_set_config), - .root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info->fdm].prach_root_sequence_index, - .restricted_set = prach_config->restricted_set_config, - .freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info->fdm].k1}; - - LOG_I(NR_MAC, - "PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", - frameP, - pdu->prach_config_pdu.prach_slot, - pdu->prach_config_pdu.prach_start_symbol, - pdu->prach_config_pdu.num_ra); - - switch (format) { // single PRACH format - case 0: - pdu->prach_config_pdu.prach_format = 0; - break; - case 1: - pdu->prach_config_pdu.prach_format = 1; - break; - case 2: - pdu->prach_config_pdu.prach_format = 2; - break; - case 3: - pdu->prach_config_pdu.prach_format = 3; - break; - case 0xa1: - pdu->prach_config_pdu.prach_format = 4; - break; - case 0xa2: - pdu->prach_config_pdu.prach_format = 5; - break; - case 0xa3: - pdu->prach_config_pdu.prach_format = 6; - break; - case 0xb1: - pdu->prach_config_pdu.prach_format = 7; - break; - case 0xb4: - pdu->prach_config_pdu.prach_format = 8; - break; - case 0xc0: - pdu->prach_config_pdu.prach_format = 9; - break; - case 0xc2: - pdu->prach_config_pdu.prach_format = 10; - break; - default: - AssertFatal(false, "Invalid PRACH format"); - } - - pdu->prach_config_pdu.ra_PreambleIndex = ra->ra_PreambleIndex; - pdu->prach_config_pdu.prach_tx_power = get_prach_tx_power(mac); - release_ul_config(pdu, false); - nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slotP, - .mac = mac, - .module_id = mac->ue_id, - .CC_id = 0 /*TBR fix*/}; - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) - mac->if_module->scheduled_response(&scheduled_response); - - T(T_UE_PHY_INITIATE_RA_PROCEDURE, T_INT(frameP), T_INT(pdu->prach_config_pdu.prach_slot), - T_INT(pdu->prach_config_pdu.ra_PreambleIndex), T_INT(pdu->prach_config_pdu.prach_tx_power)); - - const int n_slots_frame = mac->frame_structure.numb_slots_frame; - if (ra->ra_type == RA_4_STEP) { - ra->ra_state = nrRA_WAIT_RAR; - // we start to monitor DCI for RAR in the first valid occasion after transmitting RACH - // the response window timer should be started at that time - // but for processing reasons it is better to start it here and to add the slot difference - // that also takes into account the rx to tx slot offset - int next_slot = (slotP + 1) % n_slots_frame; - int next_frame = (frameP + (next_slot < slotP)) % MAX_FRAME_NUMBER; - int add_slots = 1; - NR_BWP_PDCCH_t *pdcch_config = &mac->config_BWP_PDCCH[mac->current_DL_BWP->bwp_id]; - const NR_SearchSpace_t *ra_SS = get_common_search_space(mac, pdcch_config->ra_SS_id); - while (!is_dl_slot(next_slot, &mac->frame_structure) - || !is_ss_monitor_occasion(next_frame, next_slot, n_slots_frame, ra_SS)) { - int temp_slot = (next_slot + 1) % n_slots_frame; - next_frame = (next_frame + (temp_slot < next_slot)) % MAX_FRAME_NUMBER; - next_slot = temp_slot; - add_slots++; - } - nr_timer_setup(&ra->response_window_timer, - ra->response_window_setup_time + add_slots + GET_DURATION_RX_TO_TX(&mac->ntn_ta, mac->current_DL_BWP->scs), - 1); - nr_timer_start(&ra->response_window_timer); - } else if (ra->ra_type == RA_2_STEP) { - NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource = - mac->current_UL_BWP->msgA_ConfigCommon_r16->msgA_PUSCH_Config_r16->msgA_PUSCH_ResourceGroupA_r16; - slot_t msgA_pusch_slot = (slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) % n_slots_frame; - frame_t msgA_pusch_frame = - (frameP + ((slotP + msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16) / n_slots_frame)) % 1024; - - fapi_nr_ul_config_request_pdu_t *pdu = - lockGet_ul_config(mac, msgA_pusch_frame, msgA_pusch_slot, FAPI_NR_UL_CONFIG_TYPE_PUSCH); - if (!pdu) - return; - - // Config Msg3/MsgA-PUSCH PDU - NR_tda_info_t tda_info = {0}; - AssertFatal(msgA_PUSCH_Resource->startSymbolAndLengthMsgA_PO_r16, - "Only SLIV based on startSymbolAndLengthMsgA_PO_r16 implemented\n"); - - int ret = nr_config_pusch_pdu(mac, - &tda_info, - &pdu->pusch_config_pdu, - NULL, - NULL, - NULL, - mac->ra.ra_rnti, - NR_SearchSpace__searchSpaceType_PR_common, - NR_DCI_NONE); - - if (ret != 0) - remove_ul_config_last_item(pdu); - release_ul_config(pdu, false); - - LOG_D(NR_MAC, "ra->ra_state %s\n", nrra_ue_text[ra->ra_state]); - ra->ra_state = nrRA_WAIT_MSGB; - ra->t_crnti = 0; - mac->crnti = 0; - ra->ra_rnti = 0; - } else { - AssertFatal(false, "RA type %d not implemented!\n", ra->ra_type); - } - } // is_nr_prach_slot - } // if is_nr_UL_slot + phr_info->PathlossLastValue = compute_nr_SSB_PL(mac); + // Restart both timers according to 38.321 + nr_timer_start(&phr_info->periodicPHR_Timer); + nr_timer_start(&phr_info->prohibitPHR_Timer); + phr_info->phr_reporting = 0; } typedef struct { @@ -2273,6 +1930,44 @@ typedef struct { uint32_t lcp_allocation_counter; } NR_UE_MAC_CE_INFO; +static uint8_t nr_locate_BsrIndexByBufferSize(int size, int value) +{ + if (value == 0) { + return 0; //elseif (value > 150000) return 63; + } + + uint32_t (*get_bsr_value)(int); + if (size == NR_SHORT_BSR_TABLE_SIZE) + get_bsr_value = &get_short_bsr_value; + else + get_bsr_value = &get_long_bsr_value; + + int jl = 0; // lower bound + int ju = size - 1; // upper bound + // determine the order of the the table: 1 if ascending order of table, 0 otherwise + bool ascend = (*get_bsr_value)(ju) >= (*get_bsr_value)(jl) ? 1 : 0; + while (ju - jl > 1) { //If we are not yet done, + int jm = (ju + jl) / 2; // compute a midpoint, + if ((value >= (*get_bsr_value)(jm)) == ascend) { + jl = jm; // replace the lower limit + } else { + ju = jm; //replace the upper limit + } + + LOG_T(NR_MAC, + "[UE] searching BSR index %d for (BSR TABLE %d < value %d)\n", + jm, + (*get_bsr_value)(jm), + value); + } + + if (value == (*get_bsr_value)(jl)) { + return jl; + } else { + return jl + 1; //equally ju + } +} + static void nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, @@ -2845,69 +2540,329 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, return mac_ce_info.num_sdus > 0; // success if we got at least one sdu } -static void schedule_ntn_config_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac) +void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) { - fapi_nr_dl_ntn_config_command_pdu *ntn_config_command_pdu = &dl_config->dl_config_list[dl_config->number_pdus].ntn_config_command_pdu; + int cc_id = ul_info->cc_id; + frame_t frame_tx = ul_info->frame; + slot_t slot_tx = ul_info->slot; + uint32_t gNB_index = ul_info->gNB_index; - ntn_config_command_pdu->epoch_sfn = mac->ntn_ta.epoch_sfn; - ntn_config_command_pdu->epoch_subframe = mac->ntn_ta.epoch_subframe; - ntn_config_command_pdu->cell_specific_k_offset = mac->ntn_ta.cell_specific_k_offset; - ntn_config_command_pdu->ntn_total_time_advance_ms = get_total_TA_ms(&mac->ntn_ta); - ntn_config_command_pdu->ntn_total_time_advance_drift = get_total_TA_drift(&mac->ntn_ta); - ntn_config_command_pdu->ntn_total_time_advance_drift_variant = get_total_TA_drift_variant(&mac->ntn_ta); + RA_config_t *ra = &mac->ra; - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_NTN_CONFIG_PARAMS; - dl_config->number_pdus += 1; -} - -static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac) -{ - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment; - fapi_nr_ta_command_pdu *ta = &dl_config->dl_config_list[dl_config->number_pdus].ta_command_pdu; - ta->ta_frame = ul_time_alignment->frame; - ta->ta_slot = ul_time_alignment->slot; - ta->is_rar = ul_time_alignment->ta_apply == rar_ta; - ta->ta_command = ul_time_alignment->ta_command; - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_CONFIG_TA_COMMAND; - dl_config->number_pdus += 1; - ul_time_alignment->ta_apply = no_ta; -} - -static void nr_ue_fill_phr(NR_UE_MAC_INST_t *mac, - NR_SINGLE_ENTRY_PHR_MAC_CE *phr, - float P_CMAX, - float tx_power, - frame_t frame, - slot_t slot) -{ - nr_phr_info_t *phr_info = &mac->scheduling_info.phr_info; - // Value mapping according to 38.133 10.1.18.1 - const int PC_MAX_00 = -29; - *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE){.PCMAX = max(0, (int)P_CMAX - PC_MAX_00) & 0x3f}; - // Value mapping according to 38.133 10.1.17.1.1 - const int POWER_HEADROOM_55 = 22; - int headroom = P_CMAX - tx_power; - if (headroom < POWER_HEADROOM_55) { - const int POWER_HEADROOM_0 = -32; - phr->PH = max(0, headroom - POWER_HEADROOM_0); - } else { - phr->PH = min(0x3f, 55 + (headroom - POWER_HEADROOM_55) / 2); + if (mac->state == UE_PERFORMING_RA && ra->ra_state == nrRA_UE_IDLE) { + init_RA(mac, frame_tx); + // perform the Random Access Resource selection procedure (see clause 5.1.2 and .2a) + ra_resource_selection(mac); } - LOG_D(NR_MAC, - "PHR Reporting sfn.slot %d.%d reason = %d, P_CMAX = %d (%5.2f dBm), headrom = %d (%d dB) tx_power = %5.2f dBm\n", - frame, - slot, - phr_info->phr_reporting, - phr->PCMAX, - P_CMAX, - phr->PH, - headroom, - tx_power); + if (mac->state == UE_PERFORMING_RA && ra->ra_state == nrRA_GENERATE_PREAMBLE) + nr_ue_prach_scheduler(mac, frame_tx, slot_tx); - phr_info->PathlossLastValue = compute_nr_SSB_PL(mac); - // Restart both timers according to 38.321 - nr_timer_start(&phr_info->periodicPHR_Timer); - nr_timer_start(&phr_info->prohibitPHR_Timer); - phr_info->phr_reporting = 0; + bool BSRsent = false; + if (mac->state == UE_CONNECTED) { + nr_ue_periodic_srs_scheduling(mac, frame_tx, slot_tx); + nr_update_rlc_buffers_status(mac, frame_tx, slot_tx, gNB_index); + } + + // Schedule ULSCH only if the current frame and slot match those in ul_config_req + // AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus) + uint8_t ulsch_input_buffer_array[NFAPI_MAX_NUM_UL_PDU][MAX_ULSCH_PAYLOAD_BYTES]; + int number_of_pdus = 0; + + fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = lockGet_ul_iterator(mac, frame_tx, slot_tx); + if (!ulcfg_pdu) + return; + LOG_D(NR_MAC, "number of UL PDUs: %d with UL transmission in sfn [%d.%d]\n", *ulcfg_pdu->privateNBpdus, frame_tx, slot_tx); + + while (ulcfg_pdu->pdu_type != FAPI_NR_END) { + uint8_t *ulsch_input_buffer = ulsch_input_buffer_array[number_of_pdus]; + if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { + nfapi_nr_ue_pusch_pdu_t *pdu = &ulcfg_pdu->pusch_config_pdu; + uint32_t TBS_bytes = pdu->pusch_data.tb_size; + LOG_D(NR_MAC, + "harq_id %d, new_data_indicator %d, TBS_bytes %d (ra_state %d)\n", + pdu->pusch_data.harq_process_id, + pdu->pusch_data.new_data_indicator, + TBS_bytes, + ra->ra_state); + pdu->tx_request_body.fapiTxPdu = NULL; + if ((ra->ra_state == nrRA_WAIT_RAR || ra->ra_state == nrRA_WAIT_MSGB) && !ra->cfra) { + nr_get_Msg3_MsgA_PUSCH_payload(mac, ulsch_input_buffer, TBS_bytes); + for (int k = 0; k < TBS_bytes; k++) { + LOG_D(NR_MAC, "(%i): 0x%x\n", k, ulsch_input_buffer[k]); + } + pdu->tx_request_body.fapiTxPdu = ulsch_input_buffer; + pdu->tx_request_body.pdu_length = TBS_bytes; + number_of_pdus++; + T(T_NRUE_MAC_UL_PDU_WITH_DATA, T_INT(mac->crnti), T_INT(frame_tx), T_INT(slot_tx), + T_INT(ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id), T_BUFFER(ulsch_input_buffer, TBS_bytes)); + } else { + if (ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator + && (mac->state == UE_CONNECTED || (ra->ra_state == nrRA_WAIT_RAR && ra->cfra))) { + if (!nr_timer_is_active(&mac->time_alignment_timer) && mac->state == UE_CONNECTED && !get_softmodem_params()->phy_test) { + // UL data arrival during RRC_CONNECTED when UL synchronisation status is "non-synchronised" + trigger_MAC_UE_RA(mac, NULL); + return; + } + // Getting IP traffic to be transmitted + int tx_power = pdu->tx_power; + int P_CMAX = nr_get_Pcmax(mac->p_Max, + mac->nr_band, + mac->frame_structure.frame_type, + mac->frequency_range, + mac->current_UL_BWP->channel_bandwidth, + pdu->qam_mod_order, + false, + mac->current_UL_BWP->scs, + mac->current_UL_BWP->BWPSize, + pdu->transform_precoding, + pdu->rb_size, + pdu->rb_start); + + nr_ue_get_sdu(mac, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes, tx_power, P_CMAX, &BSRsent); + pdu->tx_request_body.fapiTxPdu = ulsch_input_buffer; + pdu->tx_request_body.pdu_length = TBS_bytes; + number_of_pdus++; + T(T_NRUE_MAC_UL_PDU_WITH_DATA, T_INT(mac->crnti), T_INT(frame_tx), T_INT(slot_tx), + T_INT(ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id), T_BUFFER(ulsch_input_buffer, TBS_bytes)); + // start or restart dataInactivityTimer if any MAC entity transmits a MAC SDU for DTCH logical channel, + // or DCCH logical channel + if (mac->data_inactivity_timer) + nr_timer_start(mac->data_inactivity_timer); + } + } + + if (ra->ra_state == nrRA_WAIT_CONTENTION_RESOLUTION && !ra->cfra) { + LOG_I(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx); + // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 + // transmission + nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index); + } + if (ra->ra_state == nrRA_WAIT_RAR && !ra->cfra) { + LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); + nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index); + } + if (ra->ra_state == nrRA_WAIT_MSGB && !ra->cfra) { + LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-MsgA-PUSCH transmitted\n", frame_tx, slot_tx); + } + } + ulcfg_pdu++; + } + release_ul_config(ulcfg_pdu, false); + + if(mac->state >= UE_PERFORMING_RA && mac->state < UE_DETACHING) + nr_ue_pucch_scheduler(mac, frame_tx, slot_tx); + + if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL) { + LOG_D(NR_MAC, "3# scheduled_response transmitted,%d, %d\n", frame_tx, slot_tx); + nr_scheduled_response_t scheduled_response = {.ul_config = mac->ul_config_request + slot_tx, + .mac = mac, + .module_id = mac->ue_id, + .CC_id = cc_id, + .phy_data = ul_info->phy_data}; + mac->if_module->scheduled_response(&scheduled_response); + } + + if(mac->state == UE_CONNECTED) + nr_update_sr(mac, BSRsent); + // Global variables implicit logic + // far away, BSR_reporting_active is set + mac->scheduling_info.BSR_reporting_active = NR_BSR_TRIGGER_NONE; + + // update Bj for all active lcids before LCP procedure + if (mac->current_UL_BWP) { + LOG_D(NR_MAC, "%4d.%2d Logical Channel Prioritization\n", frame_tx, slot_tx); + for (int i = 0; i < mac->lc_ordered_list.count; i++) { + nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; + int lcid = lc_info->lcid; + // max amount of data that can be buffered/accumulated in a logical channel buffer + uint32_t bucketSize_max = lc_info->bucket_size; + // measure Bj increment the value of Bj by product PBR * T + NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid); + int32_t bj = sched_info->Bj; + if (lc_info->pbr < UINT_MAX) { + uint32_t slots_elapsed = nr_timer_elapsed_time(&sched_info->Bj_timer); // slots elapsed since Bj was last incremented + // it is safe to divide by 1k since pbr in lc_info is computed multiplying by 1000 the RRC value to convert kB/s to B/s + uint32_t pbr_ms = lc_info->pbr / 1000; + bj += ((pbr_ms * slots_elapsed) >> mac->current_UL_BWP->scs); // each slot length is 1/scs ms + } + else + bj = INT_MAX; + // bj > max bucket size, set bj to max bucket size, as in ts38.321 5.4.3.1 Logical Channel Prioritization + sched_info->Bj = min(bj, bucketSize_max); + // reset bj timer + nr_timer_start(&sched_info->Bj_timer); + } + } +} + +// PUSCH scheduler: +// - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, +// - where K2 is the offset between the slot in which UL DCI is received and the slot +// - in which ULSCH should be scheduled. K2 is configured in RRC configuration. +// PUSCH Msg3 scheduler: +// - scheduled by RAR UL grant according to 8.3 of TS 38.213 +// Note: Msg3 tx in the uplink symbols of mixed slot +int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac, + const uint8_t is_Msg3, + const frame_t current_frame, + const int current_slot, + frame_t *frame_tx, + int *slot_tx, + const long k2) +{ + int delta = 0; + const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + + // Get the numerology to calculate the Tx frame and slot + int mu = current_UL_BWP->scs; + int slots_per_frame = mac->frame_structure.numb_slots_frame; + + // k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1 + // PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon + + if (is_Msg3) { + + delta = get_delta_for_k2(mu); + + AssertFatal((k2 + delta) > GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu), + "Slot offset (%ld) for Msg3 needs to be higher than DURATION_RX_TO_TX (%ld). Please set min_rxtxtime at least to " + "%ld in gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n", + k2, + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu), + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu), + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu)); + + + *slot_tx = (current_slot + k2 + delta) % slots_per_frame; + *frame_tx = (current_frame + (current_slot + k2 + delta) / slots_per_frame) % MAX_FRAME_NUMBER; + } else { + AssertFatal(k2 >= GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu), + "Slot offset K2 (%ld) needs to be higher than DURATION_RX_TO_TX (%ld). Please set min_rxtxtime at least to %ld in " + "gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n", + k2, + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu), + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu), + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu)); + + + if (k2 < 0) { // This can happen when a false DCI is received + LOG_W(PHY, "%d.%d. Received k2 %ld\n", current_frame, current_slot, k2); + return -1; + } + + // Calculate TX slot and frame + *slot_tx = (current_slot + k2) % slots_per_frame; + *frame_tx = (current_frame + (current_slot + k2) / slots_per_frame) % MAX_FRAME_NUMBER; + } + + LOG_D(NR_MAC, "[%04d.%02d] UL transmission in [%04d.%02d] (k2 %ld delta %d)\n", current_frame, current_slot, *frame_tx, *slot_tx, k2, delta); + return 0; +} + +void configure_csi_resource_mapping(fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + const NR_CSI_RS_ResourceMapping_t *resourceMapping, + uint32_t bwp_size, + uint32_t bwp_start) +{ + // According to last paragraph of TS 38.214 5.2.2.3.1 + if (resourceMapping->freqBand.startingRB < bwp_start) + csirs_config_pdu->start_rb = bwp_start; + else + csirs_config_pdu->start_rb = resourceMapping->freqBand.startingRB; + if (resourceMapping->freqBand.nrofRBs > (bwp_start + bwp_size - csirs_config_pdu->start_rb)) + csirs_config_pdu->nr_of_rbs = bwp_start + bwp_size - csirs_config_pdu->start_rb; + else + csirs_config_pdu->nr_of_rbs = resourceMapping->freqBand.nrofRBs; + AssertFatal(csirs_config_pdu->nr_of_rbs >= 24, "CSI-RS has %d RBs, but the minimum is 24\n", csirs_config_pdu->nr_of_rbs); + + csirs_config_pdu->symb_l0 = resourceMapping->firstOFDMSymbolInTimeDomain; + if (resourceMapping->firstOFDMSymbolInTimeDomain2) + csirs_config_pdu->symb_l1 = *resourceMapping->firstOFDMSymbolInTimeDomain2; + csirs_config_pdu->cdm_type = resourceMapping->cdm_Type; + + csirs_config_pdu->freq_density = resourceMapping->density.present; + if ((resourceMapping->density.present == NR_CSI_RS_ResourceMapping__density_PR_dot5) + && (resourceMapping->density.choice.dot5 == NR_CSI_RS_ResourceMapping__density__dot5_evenPRBs)) + csirs_config_pdu->freq_density--; + + switch(resourceMapping->frequencyDomainAllocation.present){ + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1: + csirs_config_pdu->row = 1; + csirs_config_pdu->freq_domain = ((resourceMapping->frequencyDomainAllocation.choice.row1.buf[0]) >> 4) & 0x0f; + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2: + csirs_config_pdu->row = 2; + csirs_config_pdu->freq_domain = (((resourceMapping->frequencyDomainAllocation.choice.row2.buf[1] >> 4) & 0x0f) + | ((resourceMapping->frequencyDomainAllocation.choice.row2.buf[0] << 4) & 0xff0)); + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4: + csirs_config_pdu->row = 4; + csirs_config_pdu->freq_domain = ((resourceMapping->frequencyDomainAllocation.choice.row4.buf[0]) >> 5) & 0x07; + break; + case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other: + csirs_config_pdu->freq_domain = ((resourceMapping->frequencyDomainAllocation.choice.other.buf[0]) >> 2) & 0x3f; + // determining the row of table 7.4.1.5.3-1 in 38.211 + switch (resourceMapping->nrofPorts) { + case NR_CSI_RS_ResourceMapping__nrofPorts_p1: + AssertFatal(1 == 0, "Resource with 1 CSI port shouldn't be within other rows\n"); + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p2: + csirs_config_pdu->row = 3; + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p4: + csirs_config_pdu->row = 5; + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p8: + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) + csirs_config_pdu->row = 8; + else { + int num_k = 0; + for (int k = 0; k < 6; k++) + num_k += (((csirs_config_pdu->freq_domain) >> k) & 0x01); + if (num_k == 4) + csirs_config_pdu->row = 6; + else + csirs_config_pdu->row = 7; + } + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p12: + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) + csirs_config_pdu->row = 10; + else + csirs_config_pdu->row = 9; + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p16: + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) + csirs_config_pdu->row = 12; + else + csirs_config_pdu->row = 11; + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p24: + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) + csirs_config_pdu->row = 14; + else { + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) + csirs_config_pdu->row = 15; + else + csirs_config_pdu->row = 13; + } + break; + case NR_CSI_RS_ResourceMapping__nrofPorts_p32: + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) + csirs_config_pdu->row = 17; + else { + if (resourceMapping->cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) + csirs_config_pdu->row = 18; + else + csirs_config_pdu->row = 16; + } + break; + default: + AssertFatal(false, "Invalid number of ports in CSI-RS resource\n"); + } + break; + default: + AssertFatal(false, "Invalid freqency domain allocation in CSI-RS resource\n"); + } } diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 893a94147e..ed4d902345 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -708,7 +708,6 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR // precoding matrix configuration (to be improved) cfg->pmi_list = init_DL_MIMO_codebook(nrmac, pdsch_AntennaPorts); - int nb_beams = config->nb_bfw[1]; // number of beams if (nrmac->beam_info.beam_mode == PRECONFIGURED_BEAM_IDX) { LOG_I(NR_MAC, "Configuring analog beamforming in config_request message\n"); cfg->analog_beamforming_ve.num_beams_period_vendor_ext.tl.tag = NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG; @@ -717,14 +716,6 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR cfg->analog_beamforming_ve.analog_bf_vendor_ext.tl.tag = NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG; cfg->analog_beamforming_ve.analog_bf_vendor_ext.value = 1; // analog BF enabled cfg->num_tlv++; - cfg->analog_beamforming_ve.total_num_beams_vendor_ext.tl.tag = NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG; - cfg->analog_beamforming_ve.total_num_beams_vendor_ext.value = nb_beams; - cfg->num_tlv++; - cfg->analog_beamforming_ve.analog_beam_list = malloc16(nb_beams * sizeof(*cfg->analog_beamforming_ve.analog_beam_list)); - for (int i = 0; i < nb_beams; i++) { - cfg->analog_beamforming_ve.analog_beam_list[i].tl.tag = NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG; - cfg->analog_beamforming_ve.analog_beam_list[i].value = config->bw_list[i]; - } } else { cfg->analog_beamforming_ve.analog_bf_vendor_ext.value = 0; // analog BF disabled if (NFAPI_MODE == NFAPI_MONOLITHIC) { @@ -780,7 +771,7 @@ static void initialize_beam_information(NR_beam_info_t *beam_info, int mu, int s slots_per_frame); beam_info->beam_allocation_size = size / beam_info->beam_duration; for (int i = 0; i < beam_info->beams_per_period; i++) { - beam_info->beam_allocation[i] = malloc16(beam_info->beam_allocation_size * sizeof(int)); + beam_info->beam_allocation[i] = malloc16(beam_info->beam_allocation_size * sizeof(*beam_info->beam_allocation)); for (int j = 0; j < beam_info->beam_allocation_size; j++) beam_info->beam_allocation[i][j] = -1; } @@ -885,7 +876,7 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c LOG_D(NR_MAC, "Configuring common parameters from NR ServingCellConfig\n"); config_common(nrmac, config, scc); - fapi_beam_index_allocation(scc, config, nrmac); + fill_beam_index_list(scc, config, nrmac); if (NFAPI_MODE == NFAPI_MONOLITHIC) { // nothing to be sent in the other cases @@ -1065,6 +1056,24 @@ bool nr_update_sib19(const gnb_sat_position_update_t *sat_position) return true; } +bool nr_trigger_bwp_switch(uint16_t rnti, int bwp_id) +{ + gNB_MAC_INST *nrmac = RC.nrmac[0]; + NR_SCHED_LOCK(&nrmac->sched_lock); + NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, rnti); + bool success = false; + if (!UE) { + LOG_W(NR_MAC, "could not find UE for RNTI %04x\n", rnti); + } else if (UE->current_DL_BWP.bwp_id == bwp_id) { + LOG_W(NR_MAC, "UE %04x is already on BWP ID %d, not triggering reconfiguration\n", rnti, bwp_id); + } else { // UE != NULL && current_DL_BWP.bwp_id != bwp_id + nr_mac_trigger_reconfiguration(nrmac, UE, bwp_id); + success = true; + } + NR_SCHED_UNLOCK(&nrmac->sched_lock); + return success; +} + void prepare_du_configuration_update(gNB_MAC_INST *mac, f1ap_served_cell_info_t *info, NR_BCCH_BCH_Message_t *mib, @@ -1116,8 +1125,9 @@ bool nr_mac_add_test_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig_t NR_SCHED_LOCK(&nrmac->sched_lock); NR_UE_info_t *UE = get_new_nr_ue_inst(&nrmac->UE_info.uid_allocator, rnti, CellGroup); - DevAssert(UE->uid < MAX_MOBILES_PER_GNB); // test-mode: we assume we can always create a UE - free_and_zero(UE->ra); // test-mode (sims, phy-test): UE will not do RA + DevAssert(UE->uid < MAX_MOBILES_PER_GNB); // physical simulators: we assume we can always create a UE + free_and_zero(UE->ra); // physical simulators: UE will not do RA + UE->local_bwp_id = 1; // for physical simulators bool res = add_connected_nr_ue(nrmac, UE); if (!res) { LOG_E(NR_MAC, "Error adding UE %04x\n", rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index f8df95f679..5f80703c21 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -104,7 +104,7 @@ static int16_t ssb_index_from_prach(module_id_t module_idP, int config_period = cc->prach_info.x; // prach_occasion_id = subframe_index * N_t_slot * N_RA_slot * fdm + N_RA_slot_index * N_t_slot * fdm + freq_index + fdm * start_symbol_index; prach_occasion_id = - (((frameP % (cc->max_association_period * config_period)) / config_period) * cc->total_prach_occasions_per_config_period) + (((frameP % (cc->association_period * config_period)) / config_period) * cc->total_prach_occasions_per_config_period) + (RA_sfn_index + slot_index) * cc->prach_info.N_t_slot * fdm + start_symbol_index * fdm + freq_index; //one SSB have more than one continuous RO @@ -178,7 +178,7 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac) float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value]; uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value; uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value) << 32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value; - uint32_t total_RA_occasions = prach_info.N_RA_sfn * prach_info.N_t_slot * prach_info.N_RA_slot * fdm; + cc->total_prach_occasions_per_config_period = prach_info.N_RA_sfn * prach_info.N_t_slot * prach_info.N_RA_slot * fdm; for(int i = 0; i < 64; i++) { if ((L_ssb >> (63 - i)) & 0x01) { // only if the bit of L_ssb at current ssb index is 1 @@ -187,15 +187,22 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac) } } - cc->total_prach_occasions_per_config_period = total_RA_occasions; + // An association period, starting from frame 0, for mapping SS/PBCH block indexes to PRACH occasions is the smallest + // value in the set determined by the PRACH configuration period according Table 8.1-1 of 38.213 + // such that all tx SSB indexes are mapped at least once to the PRACH occasions within the association period + // An association pattern period includes one or more association periods and is determined + // so that a pattern between PRACH occasions and SS/PBCH block indexes repeats at most every 160 msec + int total_RA_occasions = 0; for (int i = 1; (1 << (i - 1)) <= prach_info.max_association_period; i++) { - cc->max_association_period = (1 << (i - 1)); - total_RA_occasions = total_RA_occasions * cc->max_association_period; - if(total_RA_occasions >= (int) (num_active_ssb / num_ssb_per_RO)) { + cc->association_period = (1 << (i - 1)); + int temp_RA_occasions = cc->total_prach_occasions_per_config_period * cc->association_period; + if(temp_RA_occasions >= (int) (num_active_ssb / num_ssb_per_RO)) { + total_RA_occasions = temp_RA_occasions; repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO) / num_active_ssb); break; } } + AssertFatal(total_RA_occasions > 0, "Couldn't find a valid association period for PRACH occasions\n"); unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition) / num_ssb_per_RO); cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion; @@ -208,7 +215,7 @@ void find_SSB_and_RO_available(gNB_MAC_INST *nrmac) cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, - cc->max_association_period, + cc->association_period, prach_info.N_RA_sfn, cc->total_prach_occasions_per_config_period); } @@ -401,7 +408,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP) nfapi_nr_prach_pdu_t *prach_pdu = &newpdu->prach_pdu; for (int td_index = 0; td_index < N_t_slot; td_index++) { uint32_t config_period = cc->prach_info.x; - prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) + + prach_occasion_id = (((frameP % (cc->association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) + (RA_sfn_index + slot_index) * N_t_slot * fdm + td_index * fdm + fdm_index; if (prach_occasion_id >= cc->total_prach_occasions) // to be confirmed: unused occasion? @@ -414,7 +421,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP) // ordered ssb number int n_ssb = (int) (prach_occasion_id / (int)(1 / num_ssb_per_RO)) % cc->num_active_ssb; // fapi beam index - beam_index = get_fapi_beamforming_index(gNB, cc->ssb_index[n_ssb]); + beam_index = get_beam_from_ssbidx(gNB, cc->ssb_index[n_ssb]); // multi-beam allocation structure beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_frame); AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to %d SSB transmitted in any available beam\n", n_ssb + 1); @@ -422,7 +429,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP) int first_ssb_index = (prach_occasion_id * (int)num_ssb_per_RO) % cc->num_active_ssb; for(int j = first_ssb_index; j < first_ssb_index + num_ssb_per_RO; j++) { // fapi beam index - beam_index = get_fapi_beamforming_index(gNB, cc->ssb_index[j]); + beam_index = get_beam_from_ssbidx(gNB, cc->ssb_index[j]); // multi-beam allocation structure beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_frame); AssertFatal(beam.idx >= 0, "Cannot allocate PRACH corresponding to SSB %d in any available beam\n", j); @@ -509,7 +516,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP) prach_pdu->beamforming.num_prgs = 1; prach_pdu->beamforming.prg_size = n_ra_rb; prach_pdu->beamforming.dig_bf_interface = num_td_occ; - prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[num_td_occ - 1].beam_idx = beam_index; + const uint16_t fapi_beam = convert_to_fapi_beam(beam_index, gNB->beam_info.beam_mode); + prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[num_td_occ - 1].beam_idx = fapi_beam; LOG_D(NR_MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n", @@ -755,8 +763,8 @@ void nr_initiate_ra_proc(module_id_t module_idP, configure_UE_BWP(nr_mac, scc, UE, true, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); // return current SSB order in the list of tranmitted SSBs int n_ssb = ssb_index_from_prach(module_idP, frame, slot, preamble_index, freq_index, symbol); - UE->UE_beam_index = get_fapi_beamforming_index(nr_mac, cc->ssb_index[n_ssb]); - + UE->UE_beam_index = get_beam_from_ssbidx(nr_mac, cc->ssb_index[n_ssb]); + LOG_I(NR_MAC, "UE %04x: Sync beam index %d\n", UE->rnti, UE->UE_beam_index); NR_SCHED_UNLOCK(&nr_mac->sched_lock); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); } @@ -893,7 +901,8 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, 0, ra->msg3_round, ul_bwp->pusch_Config && ul_bwp->pusch_Config->frequencyHopping, - UE->rnti); + UE->rnti, + nr_mac->beam_info.beam_mode); future_ul_tti_req->n_pdus += 1; // generation of DCI 0_0 to schedule msg3 retransmission @@ -926,14 +935,9 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, } // Fill PDCCH DL DCI PDU - nfapi_nr_dl_dci_pdu_t *dci_pdu = prepare_dci_pdu(pdcch_pdu_rel15, - scc, - ss, - coreset, - aggregation_level, - CCEIndex, - UE->UE_beam_index, - UE->rnti); + const uint16_t fapi_beam = convert_to_fapi_beam(UE->UE_beam_index, nr_mac->beam_info.beam_mode); + nfapi_nr_dl_dci_pdu_t *dci_pdu = + prepare_dci_pdu(pdcch_pdu_rel15, scc, ss, coreset, aggregation_level, CCEIndex, fapi_beam, UE->rnti); pdcch_pdu_rel15->numDlDci++; dci_pdu_rel15_t uldci_payload = {0}; @@ -958,7 +962,6 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, &uldci_payload, NR_UL_DCI_FORMAT_0_0, TYPE_TC_RNTI_, - ul_bwp->bwp_id, ss, coreset, 0, // parameter not needed for DCI 0_0 @@ -1198,7 +1201,8 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, slot_ 0, 0, ul_bwp->pusch_Config && ul_bwp->pusch_Config->frequencyHopping, - UE->rnti); + UE->rnti, + mac->beam_info.beam_mode); future_ul_tti_req->n_pdus += 1; // calling function to fill rar message @@ -1320,6 +1324,7 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; + const uint16_t fapi_beam = convert_to_fapi_beam(UE->UE_beam_index, nr_mac->beam_info.beam_mode); nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = prepare_pdsch_pdu(dl_tti_pdsch_pdu, nr_mac, UE, @@ -1328,19 +1333,13 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, false, round, rnti, - UE->UE_beam_index, + fapi_beam, 1, pduindex); /* Fill PDCCH DL DCI PDU */ - nfapi_nr_dl_dci_pdu_t *dci_pdu = prepare_dci_pdu(pdcch_pdu_rel15, - scc, - sched_ctrl->search_space, - coreset, - aggregation_level, - CCEIndex, - UE->UE_beam_index, - rnti); + nfapi_nr_dl_dci_pdu_t *dci_pdu = + prepare_dci_pdu(pdcch_pdu_rel15, scc, sched_ctrl->search_space, coreset, aggregation_level, CCEIndex, fapi_beam, rnti); pdcch_pdu_rel15->numDlDci++; dci_pdu_rel15_t dci_payload = prepare_dci_dl_payload(nr_mac, @@ -1385,7 +1384,6 @@ static void prepare_dl_pdus(gNB_MAC_INST *nr_mac, &dci_payload, NR_DL_DCI_FORMAT_1_0, rnti_type, - dl_bwp->bwp_id, sched_ctrl->search_space, coreset, 0, // parameter not needed for DCI 1_0 @@ -1544,8 +1542,7 @@ static void nr_generate_Msg2(module_id_t module_idP, float T_c_ns = 0.509; int numerology = ul_bwp->scs; float rtt_ns = T_c_ns * 16 * 64 / (1 << numerology) * ra->timing_offset; - float speed_of_light_in_meters_per_second = 299792458.0f; - float distance_in_meters = speed_of_light_in_meters_per_second * rtt_ns / 1000 / 1000 / 1000 / 2; + float distance_in_meters = (float) SPEED_OF_LIGHT * rtt_ns / 1000 / 1000 / 1000 / 2; LOG_A(NR_MAC, "UE %04x: %d.%d Generating RA-Msg2 DCI, RA RNTI 0x%x, state %d, preamble_index(RAPID) %d, " "timing_offset = %d (estimated distance %.1f [m])\n", diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 1f6fb64181..6dd4886911 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -114,6 +114,58 @@ static int encode_mib(NR_BCCH_BCH_Message_t *mib, frame_t frame, uint8_t *buffer return encode_size; } +static void schedule_one_ssb(gNB_MAC_INST *gNB, + nfapi_nr_dl_tti_request_body_t *dl_req, + const long band, + const NR_SubcarrierSpacing_t scs, + const int i_ssb, + const int rel_slot, + const frame_t frameP, + const slot_t slotP, + const int CC_id, + const uint8_t ssb_frame_periodicity, + const frequency_range_t FR) +{ + // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters + const int slots_per_frame = gNB->frame_structure.numb_slots_frame; + const uint16_t offset_pointa = gNB->ssb_OffsetPointA; + NR_COMMON_channels_t *cc = &gNB->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + const NR_MIB_t *mib = cc->mib->message.choice.mib; + uint32_t mib_pdu = (*(uint32_t *)cc->MIB_pdu) & ((1 << 24) - 1); + uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset; + + uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); + NR_beam_alloc_t beam = + beam_allocation_procedure(&gNB->beam_info, frameP, slotP, get_beam_from_ssbidx(gNB, i_ssb), slots_per_frame); + AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb); + const uint16_t beam_index = + convert_to_fapi_beam(get_allocated_beam(&gNB->beam_info, frameP, slotP, slots_per_frame, beam.idx), gNB->beam_info.beam_mode); + const int prb_offset = (FR == FR2) ? offset_pointa >> (scs - 2) : offset_pointa >> scs; + schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu); + fill_ssb_vrb_map(cc, + prb_offset, + (FR == FR2) ? ssbSubcarrierOffset >> (scs - 2) : ssbSubcarrierOffset, + ssb_start_symbol, + CC_id, + beam.idx); + if (IS_SA_MODE(get_softmodem_params())) { + get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], + frameP, + mib, + slots_per_frame, + ssbSubcarrierOffset, + ssb_start_symbol, + scs, + FR, + band, + i_ssb, + ssb_frame_periodicity, + prb_offset); + gNB->type0_PDCCH_CSS_config[i_ssb].active = true; + } +} + void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi_nr_dl_tti_request_t *DL_req) { gNB_MAC_INST *gNB = RC.nrmac[module_idP]; @@ -121,8 +173,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi nfapi_nr_dl_tti_request_body_t *dl_req; for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - NR_COMMON_channels_t *cc= &gNB->common_channels[CC_id]; - const NR_MIB_t *mib = cc->mib->message.choice.mib; + NR_COMMON_channels_t *cc = &gNB->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; const int slots_per_frame = gNB->frame_structure.numb_slots_frame; dl_req = &DL_req->dl_tti_request_body; @@ -143,8 +194,6 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi mib_sdu_length); } - uint32_t mib_pdu = (*(uint32_t *)cc->MIB_pdu) & ((1 << 24) - 1); - int8_t ssb_period = *scc->ssb_periodicityServingCell; uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated @@ -162,8 +211,6 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing; const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - const uint16_t offset_pointa = gNB->ssb_OffsetPointA; - uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset; const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap; const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap; @@ -175,30 +222,8 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi for (int i_ssb = 0; i_ssb < 4; i_ssb++) { if ((shortBitmap->buf[0] >> (7 - i_ssb)) & 0x01) { uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); - // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters - if ((ssb_start_symbol / 14) == rel_slot) { - int beam_index = get_fapi_beamforming_index(gNB, i_ssb); - NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_per_frame); - AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb); - const int prb_offset = offset_pointa >> scs; - schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu); - fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id, beam.idx); - if (IS_SA_MODE(get_softmodem_params())) { - get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], - frameP, - mib, - slots_per_frame, - ssbSubcarrierOffset, - ssb_start_symbol, - scs, - FR1, - band, - i_ssb, - ssb_frame_periodicity, - prb_offset); - gNB->type0_PDCCH_CSS_config[i_ssb].active = true; - } - } + if ((ssb_start_symbol / 14) == rel_slot) + schedule_one_ssb(gNB, dl_req, band, scs, i_ssb, rel_slot, frameP, slotP, CC_id, ssb_frame_periodicity, FR1); } } break; @@ -207,30 +232,8 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi for (int i_ssb = 0; i_ssb < 8; i_ssb++) { if ((mediumBitmap->buf[0] >> (7 - i_ssb)) & 0x01) { uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); - // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters - if ((ssb_start_symbol / 14) == rel_slot) { - int beam_index = get_fapi_beamforming_index(gNB, i_ssb); - NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_per_frame); - AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb); - const int prb_offset = offset_pointa >> scs; - schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu); - fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id, beam.idx); - if (IS_SA_MODE(get_softmodem_params())) { - get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], - frameP, - mib, - slots_per_frame, - ssbSubcarrierOffset, - ssb_start_symbol, - scs, - FR1, - band, - i_ssb, - ssb_frame_periodicity, - prb_offset); - gNB->type0_PDCCH_CSS_config[i_ssb].active = true; - } - } + if ((ssb_start_symbol / 14) == rel_slot) + schedule_one_ssb(gNB, dl_req, band, scs, i_ssb, rel_slot, frameP, slotP, CC_id, ssb_frame_periodicity, FR1); } } break; @@ -239,30 +242,8 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi for (int i_ssb = 0; i_ssb < 64; i_ssb++) { if ((longBitmap->buf[i_ssb / 8] >> (7 - (i_ssb % 8))) & 0x01) { uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); - // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters - if ((ssb_start_symbol / 14) == rel_slot) { - int beam_index = get_fapi_beamforming_index(gNB, i_ssb); - NR_beam_alloc_t beam = beam_allocation_procedure(&gNB->beam_info, frameP, slotP, beam_index, slots_per_frame); - AssertFatal(beam.idx >= 0, "Cannot allocate SSB %d in any available beam\n", i_ssb); - const int prb_offset = offset_pointa >> (scs-2); // reference 60kHz - schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, beam_index, ssbSubcarrierOffset, offset_pointa, mib_pdu); - fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset >> (scs - 2), ssb_start_symbol, CC_id, beam.idx); - if (IS_SA_MODE(get_softmodem_params())) { - get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], - frameP, - mib, - slots_per_frame, - ssbSubcarrierOffset, - ssb_start_symbol, - scs, - FR2, - band, - i_ssb, - ssb_frame_periodicity, - prb_offset); - gNB->type0_PDCCH_CSS_config[i_ssb].active = true; - } - } + if ((ssb_start_symbol / 14) == rel_slot) + schedule_one_ssb(gNB, dl_req, band, scs, i_ssb, rel_slot, frameP, slotP, CC_id, ssb_frame_periodicity, FR2); } } break; @@ -274,7 +255,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi } } -static void update_rb_mcs_tbs(NR_sched_pdsch_t *pdsch, uint32_t num_total_bytes, uint16_t *vrb_map) +static bool update_rb_mcs_tbs(NR_sched_pdsch_t *pdsch, uint32_t num_total_bytes, uint16_t *vrb_map) { const NR_tda_info_t *tda_info = &pdsch->tda_info; @@ -315,12 +296,15 @@ static void update_rb_mcs_tbs(NR_sched_pdsch_t *pdsch, uint32_t num_total_bytes, break; } } - AssertFatal(pdsch->tb_size >= num_total_bytes, - "Couldn't allocate enough resources for %d bytes in SIB PDSCH (rbStart %d, rbSize %d, bwpSize %d)\n", - num_total_bytes, - pdsch->rbStart, - pdsch->rbSize, - bwpSize); + if (pdsch->tb_size < num_total_bytes) { + LOG_D(NR_MAC, + "Couldn't allocate enough resources for %d bytes in SIB PDSCH (rbStart %d, rbSize %d, bwpSize %d)\n", + num_total_bytes, + pdsch->rbStart, + pdsch->rbSize, + bwpSize); + return false; + } LOG_D(NR_MAC, "mcs=%i, startSymbolIndex = %i, nrOfSymbols = %i, rbSize = %i, TBS = %i, dmrs_length %d, N_PRB_DMRS = %d, mappingtype = %d\n", @@ -332,6 +316,7 @@ static void update_rb_mcs_tbs(NR_sched_pdsch_t *pdsch, uint32_t num_total_bytes, pdsch->dmrs_parms.N_DMRS_SLOT, N_PRB_DMRS, tda_info->mapping_type); + return true; } static NR_sched_pdsch_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, @@ -361,11 +346,12 @@ static NR_sched_pdsch_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, uint8_t nr_of_candidates = 0; - for (int i=0; i<3; i++) { + for (int i = 0; i < 3; i++) { find_aggregation_candidates(&gNB_mac->sched_ctrlCommon->aggregation_level, &nr_of_candidates, gNB_mac->sched_ctrlCommon->search_space,4<0) break; // choosing the lower value of aggregation level available + if (nr_of_candidates > 0) + break; // choosing the lower value of aggregation level available } - AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n"); + AssertFatal(nr_of_candidates > 0, "nr_of_candidates is 0\n"); gNB_mac->sched_ctrlCommon->cce_index = find_pdcch_candidate(gNB_mac, CC_id, gNB_mac->sched_ctrlCommon->aggregation_level, @@ -377,18 +363,23 @@ static NR_sched_pdsch_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n"); - update_rb_mcs_tbs(&pdsch, gNB_mac->sched_ctrlCommon->num_total_bytes, vrb_map); - - // Mark the corresponding RBs as used - fill_pdcch_vrb_map(gNB_mac, - CC_id, - pdcch, - gNB_mac->sched_ctrlCommon->cce_index, - gNB_mac->sched_ctrlCommon->aggregation_level, - beam); - for (int rb = 0; rb < pdsch.rbSize; rb++) { - vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); + bool success = update_rb_mcs_tbs(&pdsch, gNB_mac->sched_ctrlCommon->num_total_bytes, vrb_map); + if (success) { + // Mark the corresponding RBs as used + fill_pdcch_vrb_map(gNB_mac, + CC_id, + pdcch, + gNB_mac->sched_ctrlCommon->cce_index, + gNB_mac->sched_ctrlCommon->aggregation_level, + beam); + for (int rb = 0; rb < pdsch.rbSize; rb++) { + vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); + } + } else { + pdsch.tb_size = 0; // to signal we couldn't allocate TBS + pdsch.time_domain_allocation = -1; } + return pdsch; } @@ -422,17 +413,9 @@ static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac, dl_tti_pdsch_pdu->PDUSize = (uint16_t)(4+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); dl_req->nPDUs += 1; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = prepare_pdsch_pdu(dl_tti_pdsch_pdu, - gNB_mac, - NULL, - pdsch, - NULL, - is_sib1, - 0, - SI_RNTI, - beam_index, - 1, - pdu_index); + const uint16_t fapi_beam = convert_to_fapi_beam(beam_index, gNB_mac->beam_info.beam_mode); + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = + prepare_pdsch_pdu(dl_tti_pdsch_pdu, gNB_mac, NULL, pdsch, NULL, is_sib1, 0, SI_RNTI, fapi_beam, 1, pdu_index); LOG_D(NR_MAC, "OtherSI:bwpStart %d, bwpSize %d, rbStart %d, rbSize %d, dlDmrsSymbPos = 0x%x\n", pdsch_pdu_rel15->BWPStart, @@ -442,14 +425,8 @@ static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac, pdsch_pdu_rel15->dlDmrsSymbPos); /* Fill PDCCH DL DCI PDU */ - nfapi_nr_dl_dci_pdu_t *dci_pdu = prepare_dci_pdu(pdcch_pdu_rel15, - scc, - search_space, - coreset, - aggregation_level, - cce_index, - beam_index, - SI_RNTI); + nfapi_nr_dl_dci_pdu_t *dci_pdu = + prepare_dci_pdu(pdcch_pdu_rel15, scc, search_space, coreset, aggregation_level, cce_index, fapi_beam, SI_RNTI); pdcch_pdu_rel15->numDlDci++; /* DCI payload */ @@ -473,7 +450,6 @@ static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac, &dci_payload, dci_format, rnti_type, - 0, search_space, coreset, 0, @@ -498,6 +474,53 @@ static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac, pdcch_pdu_rel15->numDlDci); } +static bool check_sib1_tda(gNB_MAC_INST *gNB_mac, + NR_sched_pdcch_t *sched_pdcch, + NR_beam_alloc_t *beam, + int tda, + int ssb_index, + int CC_id, + int candidate_idx) +{ + NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[ssb_index]; + default_table_type_t table_type = get_default_table_type(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern); + // If the PDSCH was scheduled with SI-RNTI in PDCCH Type0 common search space, + // the UE may assume that this PDSCH resource allocation is not applied (Table 5.1.2.1.1-4 and 5 in 38.214) + int row = tda + 1; + if (table_type == defaultB && (row == 12 || row == 13 || row == 14)) + return false; + if (table_type == defaultC && (row == 1 || row == 6 || row == 7 ||row > 12)) + return false; + // assuming normal CP + NR_tda_info_t tda_info = get_info_from_tda_tables(table_type, tda, scc->dmrs_TypeA_Position, true); + // SIB1 TDA going to the last symbol would cause overlap with CSI-RS + if (!tda_info.valid_tda || tda_info.startSymbolIndex + tda_info.nrOfSymbols == 14) + return false; + if (tda_info.startSymbolIndex < type0_PDCCH_CSS_config->first_symbol_index + type0_PDCCH_CSS_config->num_symbols) + return false; + + NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, NULL, &tda_info, 1); + // Configure sched_ctrlCommon for SIB1 + gNB_mac->sib1_pdsch[ssb_index] = schedule_control_sib1(gNB_mac, + CC_id, + sched_pdcch, + type0_PDCCH_CSS_config, + tda, + &dmrs_parms, + &tda_info, + candidate_idx, + beam->idx, + cc->sib1_bcch_length); + if (gNB_mac->sib1_pdsch[ssb_index].tb_size > 0) { + LOG_D(NR_MAC, "Found TDA for SIB1: %d\n", tda); + return true; + } else { + return false; + } +} + void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, slot_t slotP, @@ -508,12 +531,9 @@ void schedule_nr_sib1(module_id_t module_idP, // TODO: Get these values from RRC const int CC_id = 0; uint8_t candidate_idx = 0; - gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; - NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon; - - int time_domain_allocation = gNB_mac->radio_config.sib1_tda; - + NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; int L_max; switch (scc->ssb_PositionsInBurst->present) { case 1: @@ -526,8 +546,7 @@ void schedule_nr_sib1(module_id_t module_idP, L_max = 64; break; default: - AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n", - scc->ssb_PositionsInBurst->present); + AssertFatal(false, "SSB bitmap size value %d undefined (allowed values 1,2,3)\n", scc->ssb_PositionsInBurst->present); } for (int i = 0; i < L_max; i++) { @@ -543,21 +562,10 @@ void schedule_nr_sib1(module_id_t module_idP, "Trying to schedule SIB1 in slot %d which is not DL. Check searchSpaceZero configuration.\n", slotP); const int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame; - int beam_index = get_fapi_beamforming_index(gNB_mac, i); + int beam_index = get_beam_from_ssbidx(gNB_mac, i); NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frameP, slotP, beam_index, n_slots_frame); AssertFatal(beam.idx >= 0, "Cannot allocate SIB1 corresponding to SSB %d in any available beam\n", i); LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index); - - default_table_type_t table_type = get_default_table_type(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern); - // assuming normal CP - NR_tda_info_t tda_info = get_info_from_tda_tables(table_type, time_domain_allocation, scc->dmrs_TypeA_Position, true); - - AssertFatal((tda_info.startSymbolIndex + tda_info.nrOfSymbols) < 14, - "SIB1 TDA %d would cause overlap with CSI-RS. Please select a different SIB1 TDA.\n", - time_domain_allocation); - - NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, NULL, &tda_info, 1); - NR_sched_pdcch_t sched_pdcch = set_pdcch_structure(NULL, gNB_mac->sched_ctrlCommon->search_space, gNB_mac->sched_ctrlCommon->coreset, @@ -565,23 +573,24 @@ void schedule_nr_sib1(module_id_t module_idP, NULL, type0_PDCCH_CSS_config); - NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0]; - // Configure sched_ctrlCommon for SIB1 - NR_sched_pdsch_t sched_pdsch = schedule_control_sib1(gNB_mac, - CC_id, - &sched_pdcch, - type0_PDCCH_CSS_config, - time_domain_allocation, - &dmrs_parms, - &tda_info, - candidate_idx, - beam.idx, - cc->sib1_bcch_length); - + bool res = false; + if (gNB_mac->sib1_pdsch[i].time_domain_allocation < 0) { + for (int t = 0; t < 16; t++) { + if (check_sib1_tda(gNB_mac, &sched_pdcch, &beam, t, i, CC_id, candidate_idx)) { + res = true; + break; + } + } + } + AssertFatal(gNB_mac->sib1_pdsch[i].time_domain_allocation >= 0, "Couldn't select any TDA for SIB1\n"); + if (!res) + res = check_sib1_tda(gNB_mac, &sched_pdcch, &beam, gNB_mac->sib1_pdsch[i].time_domain_allocation, i, CC_id, candidate_idx); + int tb_size = gNB_mac->sib1_pdsch[i].tb_size; + AssertFatal(res && tb_size > 0, "Couldn't allocate TB for SIB1 for an already allocated TDA\n"); nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; int pdu_index = gNB_mac->pdu_index[0]++; nr_fill_nfapi_dl_SIB_pdu(gNB_mac, - &sched_pdsch, + &gNB_mac->sib1_pdsch[i], &sched_pdcch, gNB_mac->sched_ctrlCommon->search_space, gNB_mac->sched_ctrlCommon->coreset, @@ -597,11 +606,11 @@ void schedule_nr_sib1(module_id_t module_idP, nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req]; // Data to be transmitted - memcpy(tx_req->TLVs[0].value.direct, cc->sib1_bcch_pdu, sched_pdsch.tb_size); + memcpy(tx_req->TLVs[0].value.direct, cc->sib1_bcch_pdu, tb_size); tx_req->PDU_index = pdu_index; tx_req->num_TLV = 1; - tx_req->TLVs[0].length = sched_pdsch.tb_size; + tx_req->TLVs[0].length = tb_size; tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, tx_req->TLVs[0].length); TX_req->Number_of_PDUs++; TX_req->SFN = frameP; @@ -651,6 +660,7 @@ static void other_sib_sched_control(module_id_t module_idP, slot); NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[0].ServingCellConfigCommon; int n_slots_frame = gNB_mac->frame_structure.numb_slots_frame; + beam_index = get_beam_from_ssbidx(gNB_mac, beam_index); NR_beam_alloc_t beam = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, beam_index, n_slots_frame); AssertFatal(beam.idx >= 0, "Cannot allocate otherSIB corresponding for SSB number %d in any available beam\n", beam_index); LOG_D(NR_MAC, "(%d.%d) otherSIB payload %d transmission for ssb number %d\n", frame, slot, payload_idx, beam_index); @@ -706,7 +716,8 @@ static void other_sib_sched_control(module_id_t module_idP, uint16_t *vrb_map = cc->vrb_map[beam.idx]; uint8_t *sib_bcch_pdu = cc->other_sib_bcch_pdu[payload_idx]; int num_total_bytes = cc->other_sib_bcch_length[payload_idx]; - update_rb_mcs_tbs(&sched_pdsch_otherSI, num_total_bytes, vrb_map); + bool success = update_rb_mcs_tbs(&sched_pdsch_otherSI, num_total_bytes, vrb_map); + AssertFatal(success, "Couldn't allocate TBS for other SIB\n"); for (int rb = 0; rb < sched_pdsch_otherSI.rbSize; rb++) { vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 222bc33671..5bdf233908 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -398,17 +398,19 @@ bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE) // except for the case when DCI format 1_0 is decoded in any common search space in which case the size of CORESET 0 shall be // used if CORESET 0 is configured for the cell and the size of initial DL bandwidth part shall be used if CORESET 0 is not // configured for the cell. - if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0 && sched_ctrl->search_space->searchSpaceType + if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0 + && sched_ctrl->search_space->searchSpaceType && sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) { if (sched_ctrl->coreset->controlResourceSetId == 0) { bwp_info.bwpStart = nr_mac->cset0_bwp_start; } else { - bwp_info.bwpStart = dl_bwp->BWPStart + sched_ctrl->sched_pdcch.rb_start; + int additional_offset = (dl_bwp->BWPStart + 5) / 6 * 6 - dl_bwp->BWPStart; + bwp_info.bwpStart = dl_bwp->BWPStart + sched_ctrl->sched_pdcch.rb_start + additional_offset; } if (nr_mac->cset0_bwp_size > 0) { - bwp_info.bwpSize = min(dl_bwp->BWPSize - bwp_info.bwpStart, nr_mac->cset0_bwp_size); + bwp_info.bwpSize = min(dl_bwp->BWPSize, nr_mac->cset0_bwp_size); } else { - bwp_info.bwpSize = min(dl_bwp->BWPSize - bwp_info.bwpStart, UE->sc_info.initial_dl_BWPSize); + bwp_info.bwpSize = min(dl_bwp->BWPSize, UE->sc_info.initial_dl_BWPSize); } } else { bwp_info.bwpSize = dl_bwp->BWPSize; @@ -592,6 +594,21 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, return true; } +static void ack_reconfig(gNB_MAC_INST *mac, NR_UE_info_t *UE) +{ + if (!UE->reconfigCellGroup) { + LOG_W(NR_MAC, "Received ACK for RRCReconfiguration, but nothing to apply!\n"); + return; + } + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); + UE->CellGroup = UE->reconfigCellGroup; + UE->reconfigCellGroup = NULL; + NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; + /* clean BWP structures */ + clean_bwp_structures(UE->CellGroup->spCellConfig); + configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); +} + typedef struct UEsched_s { float coef; NR_UE_info_t * UE; @@ -866,6 +883,12 @@ static void pf_dl(gNB_MAC_INST *mac, .tda_info = tda_info, }; + sched_pdsch.action = NULL; + int srb1 = 1; + /* everything that's only 3 bytes is an ack. To be safe, use a bit more. */ + if (iterator->UE->reconfigCellGroup && sched_ctrl->rlc_status[srb1].bytes_in_buffer > 10) + sched_pdsch.action = ack_reconfig; + // Fix me: currently, the RLC does not give us the total number of PDUs // awaiting. Therefore, for the time being, we put a fixed overhead of 12 // (for 4 PDUs) and optionally + 2 for TA. Once RLC gives the number of @@ -1161,6 +1184,7 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE maxMIMO_Layers = 1; } const int nl_tbslbrm = min(maxMIMO_Layers, 4); + const uint16_t fapi_beam = convert_to_fapi_beam(UE->UE_beam_index, nr_mac->beam_info.beam_mode); nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu = prepare_pdsch_pdu(dl_tti_pdsch_pdu, nr_mac, UE, @@ -1169,7 +1193,7 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE false, harq->round, rnti, - UE->UE_beam_index, + fapi_beam, nl_tbslbrm, pduindex); @@ -1182,7 +1206,7 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE sched_ctrl->coreset, sched_ctrl->aggregation_level, sched_ctrl->cce_index, - UE->UE_beam_index, + fapi_beam, rnti); pdcch_pdu->numDlDci++; @@ -1232,7 +1256,6 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE &dci_payload, current_BWP->dci_format, rnti_type, - bwp_id, sched_ctrl->search_space, sched_ctrl->coreset, UE->pdsch_HARQ_ACK_Codebook, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index f9121b3125..f23dfe8b30 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -92,14 +92,34 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch) const int bwpSize = dl_bwp->BWPSize; const int BWPStart = dl_bwp->BWPStart; - // TODO implement beam procedures for phy-test mode - int beam = 0; + /* This is a primitive beam allocation procedure for PDSCH in phytest mode which is + intended to be used to verify the beamformed signal in VSA. The beam allocation of PDSCH + slots follows the SSB slots even in slots that don't have SSB. */ + uint8_t num_ssb = 0; + const uint64_t ssbBitmap = get_ssb_bitmap_and_len(scc, &num_ssb); + int ssb_idx_beam = 0; + for (int i_ssb = 0; i_ssb < num_ssb; i_ssb++) { + if (IS_BIT_SET(ssbBitmap, (63 - i_ssb))) { + NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing; + const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + uint16_t ssb_start_symbol = get_ssb_start_symbol(band, scs, i_ssb); + // select beam for PDSCH in current slot based on SSB beam + if ((ssb_start_symbol / NR_NUMBER_OF_SYMBOLS_PER_SLOT) == (slot % mac->frame_structure.numb_slots_period)) { + ssb_idx_beam = i_ssb; + break; + } + } + } + int beam_idx = get_beam_from_ssbidx(mac, ssb_idx_beam); + NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, frame, slot, beam_idx, mac->frame_structure.numb_slots_frame); + AssertFatal(beam.idx > -1, "Can't allocate beam %d in phytest scheduler\n", beam_idx); + UE->UE_beam_index = get_allocated_beam(&mac->beam_info, frame, slot, mac->frame_structure.numb_slots_frame, beam.idx); int rbStart = 0; int rbSize = 0; if (target_dl_bw>bwpSize) target_dl_bw = bwpSize; - uint16_t *vrb_map = mac->common_channels[CC_id].vrb_map[beam]; + uint16_t *vrb_map = mac->common_channels[CC_id].vrb_map[beam.idx]; /* loop ensures that we allocate exactly target_dl_bw, or return */ while (true) { /* advance to first free RB */ @@ -132,9 +152,11 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch) sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; int CCEIndex = get_cce_index(mac, - CC_id, slot, UE->rnti, + CC_id, + slot, + UE->rnti, &sched_ctrl->aggregation_level, - beam, + beam.idx, sched_ctrl->search_space, sched_ctrl->coreset, &sched_ctrl->sched_pdcch, @@ -156,12 +178,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch) sched_ctrl->cce_index = CCEIndex; - fill_pdcch_vrb_map(mac, - CC_id, - &sched_ctrl->sched_pdcch, - CCEIndex, - sched_ctrl->aggregation_level, - beam); + fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam.idx); NR_sched_pdsch_t sched_pdsch = { .rbSize = rbSize, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index a5e4c771fd..46dac61fed 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -521,6 +521,7 @@ static NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc, /// @param rb_start Output parameter for the starting resource block index of the CORESET static void get_coreset_rb_params(const NR_ControlResourceSet_t *coreset, uint16_t *n_rb, uint16_t *rb_start) { + AssertFatal(!coreset->ext1 || !coreset->ext1->rb_Offset_r16, "rb-Offset in coreset configuration not handled\n"); *n_rb = 0; *rb_start = 0; @@ -974,8 +975,10 @@ dci_pdu_rel15_t prepare_dci_dl_payload(const gNB_MAC_INST *gNB_mac, dci_payload.dai[0].val = pucch ? (pucch->dai_c - 1) & 3 : 0; // bwp indicator // as per table 7.3.1.1.2-1 in 38.212 - if (dl_BWP) - dci_payload.bwp_indicator.val = UE->sc_info.n_dl_bwp < 4 ? dl_BWP->bwp_id : dl_BWP->bwp_id - 1; + if (dl_BWP) { + int ext_bwp_id = dl_BWP->bwp_id ? 1 : 0; // BWP-ID sent to the UE is always 1 except for BWP 0 + dci_payload.bwp_indicator.val = UE->sc_info.n_dl_bwp < 4 ? ext_bwp_id : ext_bwp_id - 1; + } return dci_payload; } @@ -1249,7 +1252,6 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info, NR_UE_UL_BWP_t *ul_bwp, NR_SearchSpace__searchSpaceType_PR ss_type) { - int bwp_id = ul_bwp->bwp_id; nr_dci_format_t dci_format = ul_bwp->dci_format; // 3GPP TS 38.214 Section 6.1.2.2.2 Uplink resource allocation type 1 @@ -1281,7 +1283,8 @@ void config_uldci(const NR_UE_ServingCell_Info_t *sc_info, LOG_D(NR_MAC,"Configuring DCI Format 0_1\n"); dci_pdu_rel15->dai[0].val = 0; //TODO // bwp indicator as per table 7.3.1.1.2-1 in 38.212 - dci_pdu_rel15->bwp_indicator.val = sc_info->n_ul_bwp < 4 ? bwp_id : bwp_id - 1; + int ext_bwp_id = ul_bwp->bwp_id ? 1 : 0; // BWP-ID sent to the UE is always 1 except for BWP 0 + dci_pdu_rel15->bwp_indicator.val = sc_info->n_ul_bwp < 4 ? ext_bwp_id : ext_bwp_id - 1; // SRS resource indicator if (pusch_Config && pusch_Config->txConfig != NULL) { AssertFatal(*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook, @@ -1391,7 +1394,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t *pucch_pdu, uint16_t O_csi, uint16_t O_ack, uint8_t O_sr, - int r_pucch) + int r_pucch, + nr_beam_mode_t beam_mode) { NR_PUCCH_Resource_t *pucchres; NR_PUCCH_FormatConfig_t *pucchfmt; @@ -1599,7 +1603,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t *pucch_pdu, pucch_pdu->beamforming.num_prgs = 1; pucch_pdu->beamforming.prg_size = pucch_pdu->prb_size; pucch_pdu->beamforming.dig_bf_interface = 1; - pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; + const uint16_t fapi_beam = convert_to_fapi_beam(UE->UE_beam_index, beam_mode); + pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = fapi_beam; } void set_r_pucch_parms(int rsetindex, @@ -1707,7 +1712,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, dci_pdu_rel15_t *dci_pdu_rel15, int dci_format, int rnti_type, - int bwp_id, NR_SearchSpace_t *ss, NR_ControlResourceSet_t *coreset, long pdsch_HARQ_ACK_Codebook, @@ -1738,7 +1742,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, NR_UL_DCI_FORMAT_0_0, rnti_type, coreset, - bwp_id, ss->searchSpaceType->present, cset0_bwp_size, 0); @@ -1752,7 +1755,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, NR_DL_DCI_FORMAT_1_0, rnti_type, coreset, - bwp_id, ss->searchSpaceType->present, cset0_bwp_size, 0); @@ -1769,10 +1771,10 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, dci_format, rnti_type, coreset, - bwp_id, ss->searchSpaceType->present, cset0_bwp_size, alt_size); + if (dci_size == 0) return; pdcch_dci_pdu->PayloadSizeBits = dci_size; @@ -2556,7 +2558,7 @@ NR_UE_info_t *find_ra_UE(NR_UEs_t *UEs, rnti_t rntiP) void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia) { ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); - ASN_STRUCT_FREE(asn_DEF_NR_SpCellConfig, UE->reconfigSpCellConfig); + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup); ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; seq_arr_free(&sched_ctrl->lc_config, NULL); @@ -2770,38 +2772,26 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, AssertFatal(dl_bwp_switch == ul_bwp_switch, "Different UL and DL BWP not supported\n"); DL_BWP->bwp_id = dl_bwp_switch; UL_BWP->bwp_id = ul_bwp_switch; + UE->local_bwp_id = dl_bwp_switch; // assuming they are the same } else { - // (re)configuring BWP - // TODO BWP switching not via RRC reconfiguration - // via RRC if firstActiveXlinkBWP_Id is NULL, MAC stays on the same BWP as before - if (servingCellConfig->firstActiveDownlinkBWP_Id) - DL_BWP->bwp_id = *servingCellConfig->firstActiveDownlinkBWP_Id; - if (servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id) - UL_BWP->bwp_id = *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id; + DL_BWP->bwp_id = UE->local_bwp_id; + UL_BWP->bwp_id = UE->local_bwp_id; } const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList; if(bwpList) - sc_info->n_dl_bwp = bwpList->list.count; - if (DL_BWP->bwp_id>0) { - for (int i=0; ilist.count; i++) { - dl_bwp = bwpList->list.array[i]; - if(dl_bwp->bwp_Id == DL_BWP->bwp_id) - break; - } - AssertFatal(dl_bwp!=NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n",DL_BWP->bwp_id); + sc_info->n_dl_bwp = 1; + if (DL_BWP->bwp_id > 0) { + dl_bwp = bwpList->list.array[0]; + AssertFatal(dl_bwp, "Couldn't find DLBWP corresponding to BWP ID %ld\n", DL_BWP->bwp_id); } const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList; if(ubwpList) - sc_info->n_ul_bwp = ubwpList->list.count; - if (UL_BWP->bwp_id>0) { - for (int i=0; ilist.count; i++) { - ul_bwp = ubwpList->list.array[i]; - if(ul_bwp->bwp_Id == UL_BWP->bwp_id) - break; - } - AssertFatal(ul_bwp!=NULL,"Couldn't find ULBWP corresponding to BWP ID %ld\n",UL_BWP->bwp_id); + sc_info->n_ul_bwp = 1; + if (UL_BWP->bwp_id > 0) { + ul_bwp = ubwpList->list.array[0]; + AssertFatal(ul_bwp, "Couldn't find ULBWP corresponding to BWP ID %ld\n", UL_BWP->bwp_id); } // selection of dedicated BWPs @@ -2829,12 +2819,12 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, } // TDA lists - if (DL_BWP->bwp_id>0) + if (DL_BWP->bwp_id > 0) DL_BWP->tdaList_Common = dl_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; else DL_BWP->tdaList_Common = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - if(UL_BWP->bwp_id>0) + if(UL_BWP->bwp_id > 0) UL_BWP->tdaList_Common = ul_bwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; else UL_BWP->tdaList_Common = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; @@ -2932,6 +2922,20 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, sc_info->nrofHARQ_ProcessesForPUSCH_r17 = pusch_servingcellconfig->ext3->nrofHARQ_ProcessesForPUSCH_r17; } } + } else { + sc_info->csi_MeasConfig = NULL; + sc_info->nrofHARQ_ProcessesForPDSCH = NULL; + sc_info->maxMIMO_Layers_PDSCH = NULL; + sc_info->downlinkHARQ_FeedbackDisabled_r17 = NULL; + sc_info->pdsch_CGB_Transmission = NULL; + sc_info->nrofHARQ_ProcessesForPDSCH_v1700 = NULL; + sc_info->crossCarrierSchedulingConfig = NULL; + sc_info->supplementaryUplink = NULL; + sc_info->carrierSwitching = NULL; + sc_info->maxMIMO_Layers_PUSCH = NULL; + sc_info->rateMatching_PUSCH = NULL; + sc_info->pusch_CGB_Transmission = NULL; + sc_info->nrofHARQ_ProcessesForPUSCH_r17 = NULL; } if (CellGroup && CellGroup->physicalCellGroupConfig) @@ -3284,9 +3288,10 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt NR_NZP_CSI_RS_ResourceSetId_t *nzp = NULL; for (int csi_list=0; csi_listcsi_ResourceConfigToAddModList->list.count; csi_list++) { NR_CSI_ResourceConfig_t *csires = csi_measconfig->csi_ResourceConfigToAddModList->list.array[csi_list]; - if(csires->bwp_Id == dl_bwp->bwp_id && - csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB && - csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) { + if (csires->bwp_Id > 1) + LOG_E(NR_MAC, "Invalid CSI resource BWP ID %ld, we only configure BWP up to 1\n", csires->bwp_Id); + else if (csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB && + csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) { nzp = csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0]; } } @@ -3325,7 +3330,8 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, slot_t slot, nfapi_nr_dl_tt csirs_pdu_rel15->precodingAndBeamforming.prg_size = resourceMapping.freqBand.nrofRBs; //1 PRG of max size csirs_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 1; csirs_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; - csirs_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; + const uint16_t fapi_beam = convert_to_fapi_beam(UE->UE_beam_index, gNB_mac->beam_info.beam_mode); + csirs_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = fapi_beam; csirs_pdu_rel15->bwp_size = dl_bwp->BWPSize; csirs_pdu_rel15->bwp_start = dl_bwp->BWPStart; csirs_pdu_rel15->subcarrier_spacing = dl_bwp->scs; @@ -3523,46 +3529,11 @@ void nr_measgap_scheduling(gNB_MAC_INST *nr_mac, frame_t frame, sub_frame_t slot void clean_bwp_structures(NR_SpCellConfig_t *spCellConfig) { NR_ServingCellConfig_t *spCellConfigDedicated = spCellConfig->spCellConfigDedicated; - if (spCellConfigDedicated->downlinkBWP_ToReleaseList) { - struct NR_ServingCellConfig__downlinkBWP_ToReleaseList *rel_dl = spCellConfigDedicated->downlinkBWP_ToReleaseList; - struct NR_ServingCellConfig__downlinkBWP_ToAddModList *add_dl = spCellConfigDedicated->downlinkBWP_ToAddModList; - int num_rel = rel_dl->list.count; - int num_add = add_dl->list.count; - for (int i = 0; i < num_rel; i++) { - NR_BWP_Id_t *rel_id = rel_dl->list.array[i]; - for (int j = 0; j < num_add; j++) { - NR_BWP_Downlink_t *dl_bwp = add_dl->list.array[j]; - if (*rel_id == dl_bwp->bwp_Id) { - asn_sequence_del(&add_dl->list, j, 1); - } - } - asn_sequence_del(&rel_dl->list, i, 1); - } - if (rel_dl->list.count == 0) - free_and_zero(rel_dl); - if (add_dl->list.count == 0) - free_and_zero(add_dl); - } - if (spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList) { - struct NR_UplinkConfig__uplinkBWP_ToReleaseList *rel_ul = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList; - struct NR_UplinkConfig__uplinkBWP_ToAddModList *add_ul = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList; - int num_rel = rel_ul->list.count; - int num_add = add_ul->list.count; - for (int i = 0; i < num_rel; i++) { - NR_BWP_Id_t *rel_id = rel_ul->list.array[i]; - for (int j = 0; j < num_add; j++) { - NR_BWP_Uplink_t *ul_bwp = add_ul->list.array[j]; - if (*rel_id == ul_bwp->bwp_Id) { - asn_sequence_del(&add_ul->list, j, 1); - } - } - asn_sequence_del(&rel_ul->list, i, 1); - } - if (rel_ul->list.count == 0) - free_and_zero(rel_ul); - if (add_ul->list.count == 0) - free_and_zero(add_ul); - } + if (spCellConfigDedicated->downlinkBWP_ToAddModList && spCellConfigDedicated->downlinkBWP_ToAddModList->list.count > 1) + asn_sequence_del(&spCellConfigDedicated->downlinkBWP_ToAddModList->list, 0, 1); + if (spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList + && spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count > 1) + asn_sequence_del(&spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list, 0, 1); } void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) @@ -3584,8 +3555,6 @@ void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) /* remove reestablishRLC, we don't need it anymore */ for (int i = 0; i < cell_group->rlc_BearerToAddModList->list.count; ++i) free_and_zero(cell_group->rlc_BearerToAddModList->list.array[i]->reestablishRLC); - /* clean BWP structures */ - clean_bwp_structures(spCellConfig); } int nr_mac_get_reconfig_delay_slots(NR_SubcarrierSpacing_t scs) @@ -3735,45 +3704,48 @@ void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t } } -int get_fapi_beamforming_index(gNB_MAC_INST *mac, int ssb_idx) +int get_beam_from_ssbidx(gNB_MAC_INST *mac, int ssb_idx) { - int beam_idx = mac->fapi_beam_index[ssb_idx]; + int beam_idx = mac->beam_index_list[ssb_idx]; AssertFatal(beam_idx >= 0, "Invalid beamforming index %d\n", beam_idx); return beam_idx; } -// TODO this is a placeholder for a possibly more complex function -// for now the fapi beam index is the number of SSBs transmitted before ssb_index i -void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config, gNB_MAC_INST *mac) +uint64_t get_ssb_bitmap_and_len(const NR_ServingCellConfigCommon_t *scc, uint8_t *len) { - if (mac->beam_info.beam_mode == NO_BEAM_MODE) - return; - int len = 0; - uint8_t* buf = NULL; switch (scc->ssb_PositionsInBurst->present) { case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap: - len = 4; - buf = scc->ssb_PositionsInBurst->choice.shortBitmap.buf; + *len = 4; break; case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap: - len = 8; - buf = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf; + *len = 8; break; case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap: - len = 64; - buf = scc->ssb_PositionsInBurst->choice.longBitmap.buf; + *len = 64; break; default : AssertFatal(false, "Invalid configuration\n"); } + return get_ssb_bitmap(scc); +} + +// TODO this is a placeholder for a possibly more complex function +// for now the fapi beam index is the number of SSBs transmitted before ssb_index i +void fill_beam_index_list(NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config, gNB_MAC_INST *mac) +{ + if (mac->beam_info.beam_mode == NO_BEAM_MODE) + return; + + uint8_t len = 0; + const uint64_t ssbBitmap = get_ssb_bitmap_and_len(scc, &len); int index = 0; for (int i = 0; i < len; ++i) { - if ((buf[i / 8] >> (7 - i % 8)) & 0x1) { + if (IS_BIT_SET(ssbBitmap, (63 - i))) { int fapi_index = mac->beam_info.beam_mode == LOPHY_BEAM_IDX ? config->bw_list[index] : index; - mac->fapi_beam_index[i] = fapi_index; + mac->beam_index_list[i] = fapi_index; index++; } else - mac->fapi_beam_index[i] = -1; + mac->beam_index_list[i] = -1; } } @@ -3782,7 +3754,7 @@ static inline int get_beam_index(const NR_beam_info_t *beam_info, int frame, int return ((frame * slots_per_frame + slot) / beam_info->beam_duration) % beam_info->beam_allocation_size; } -NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame) +NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame) { // if no beam allocation for analog beamforming we always return beam index 0 (no multiple beams) if (beam_info->beam_mode == NO_BEAM_MODE) @@ -3791,7 +3763,7 @@ NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, const int index = get_beam_index(beam_info, frame, slot, slots_per_frame); for (int i = 0; i < beam_info->beams_per_period; i++) { NR_beam_alloc_t beam_struct = {.new_beam = false, .idx = i}; - int *beam = &beam_info->beam_allocation[i][index]; + int16_t *beam = &beam_info->beam_allocation[i][index]; if (*beam == -1) { beam_struct.new_beam = true; *beam = beam_index; @@ -3805,7 +3777,23 @@ NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, return (NR_beam_alloc_t) {.new_beam = false, .idx = -1}; } -void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame, bool new_beam) +uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode) +{ + AssertFatal(beam_idx >= 0 && beam_idx < 32768, "Beam index out of range. Valid range is [0, 32767]\n"); + return (mode == LOPHY_BEAM_IDX) ? SET_BIT(beam_idx, 15) : beam_idx; +} + +int16_t get_allocated_beam(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame, int beam_number_in_period) +{ + int16_t beam_idx = 0; + if (beam_info->beam_mode != NO_BEAM_MODE) { + const int index = get_beam_index(beam_info, frame, slot, slots_per_frame); + beam_idx = beam_info->beam_allocation[beam_number_in_period][index]; + } + return beam_idx; +} + +void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, bool new_beam) { if(!new_beam) // need to reset only if the beam was allocated specifically for this instance return; @@ -3823,7 +3811,7 @@ void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE) return; RSRP_report_t *rsrp_report = &UE->UE_sched_ctrl.CSI_report.ssb_rsrp_report; // simple beam switching algorithm -> we select beam with highest RSRP from CSI report - int new_bf_index = get_fapi_beamforming_index(mac, rsrp_report->resource_id[0]); + int new_bf_index = get_beam_from_ssbidx(mac, rsrp_report->resource_id[0]); if (UE->UE_beam_index == new_bf_index) return; // no beam change needed @@ -3885,6 +3873,7 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config); ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = cellGroupConfig; + UE->local_bwp_id = mac->radio_config.first_active_bwp; if (!cellGroupConfig) return true; @@ -3991,15 +3980,35 @@ bool nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t * return false; } -void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE, int new_bwp_id) +static bool verify_bwp_switch(const NR_UE_info_t *UE, const nr_mac_config_t *configuration, int new_bwp_id) +{ + if (new_bwp_id == UE->current_DL_BWP.bwp_id) { + LOG_E(NR_MAC, "Source BWP ID and target BWP ID are the same, can't perform switch\n"); + return false; + } + + if (new_bwp_id == 0) + return true; + for (int i = 0; i < configuration->num_additional_bwps; i++) { + const nr_bwp_config_t *bwp_config = &configuration->bwp_config[i]; + if (bwp_config->id == new_bwp_id) + return true; + } + LOG_E(NR_MAC, "New BWP %d does not belong to the list of configured BWPs, can't perform switch\n", new_bwp_id); + return false; +} + +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id) { DevAssert(UE->CellGroup != NULL); NR_CellGroupConfig_t *cellGroup_for_UE = NULL; if (new_bwp_id >= 0) { AssertFatal(UE->current_DL_BWP.bwp_id == UE->current_UL_BWP.bwp_id, "We only support same BWP for UL and DL\n"); - if (new_bwp_id == UE->current_DL_BWP.bwp_id) - LOG_E(NR_MAC, "Source BWP ID and target BWP ID are the same, can't perform switch\n"); - else + if (!verify_bwp_switch(UE, &nrmac->radio_config, new_bwp_id)) + return; + else { + UE->sc_info.csi_MeasConfig = NULL; // to avoid segfault when freeing csi_MeasConfig in configDedicated + UE->local_bwp_id = new_bwp_id; cellGroup_for_UE = update_cellGroupConfig_for_BWP_switch(UE->CellGroup, &nrmac->radio_config, UE->capability, @@ -4007,6 +4016,7 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_ UE->uid, UE->current_DL_BWP.bwp_id, new_bwp_id); + } } uint8_t buf[2048]; asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, @@ -4015,6 +4025,8 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_ buf, sizeof(buf)); AssertFatal(enc_rval.encoded > 0, "ASN1 encoding of CellGroupConfig failed, failed type %s\n", enc_rval.failed_type->name); + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup); + UE->reconfigCellGroup = cellGroup_for_UE; du_to_cu_rrc_information_t du2cu = { .cellGroupConfig = buf, .cellGroupConfig_length = (enc_rval.encoded + 7) >> 3, @@ -4028,8 +4040,6 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_ .cause_value = F1AP_CauseRadioNetwork_action_desirable_for_radio_reasons, }; nrmac->mac_rrc.ue_context_modification_required(&required); - if (cellGroup_for_UE) - free_cellGroupConfig(cellGroup_for_UE); } long get_lcid_from_drbid(int drb_id) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index cf58252ed9..1afa2d1502 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -428,7 +428,7 @@ static void nr_configure_srs(gNB_MAC_INST *nrmac, srs_pdu->num_ant_ports = srs_resource->nrofSRS_Ports; srs_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols; srs_pdu->num_repetitions = srs_resource->resourceMapping.repetitionFactor; - srs_pdu->time_start_position = NR_NUMBER_OF_SYMBOLS_PER_SLOT - 1 - srs_resource->resourceMapping.startPosition; + srs_pdu->time_start_position = srs_resource->resourceMapping.startPosition; srs_pdu->config_index = srs_resource->freqHopping.c_SRS; srs_pdu->sequence_id = srs_resource->sequenceId; srs_pdu->bandwidth_index = srs_resource->freqHopping.b_SRS; @@ -473,12 +473,14 @@ static void nr_configure_srs(gNB_MAC_INST *nrmac, srs_pdu->beamforming.num_prgs = m_SRS[srs_pdu->config_index]; srs_pdu->beamforming.prg_size = srs_pdu->srs_parameters_v4.srs_bandwidth_size; } - srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; + const uint16_t fapi_beam = convert_to_fapi_beam(UE->UE_beam_index, nrmac->beam_info.beam_mode); + srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = fapi_beam; NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame); AssertFatal(beam.idx >= 0, "Cannot allocate SRS in any available beam\n"); uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE]; uint16_t num = 1 << srs_pdu->num_symbols; // 0,1,2 means 1,2,4 symbols, see 222.10.04 table 3-105 - uint16_t mask = SL_to_bitmap(srs_pdu->time_start_position, num); + const uint8_t l0 = NR_NUMBER_OF_SYMBOLS_PER_SLOT - 1 - srs_pdu->time_start_position; + uint16_t mask = SL_to_bitmap(l0, num); DevAssert(mask != 0); for (int i = 0; i < srs_pdu->bwp_size; ++i) { int rb = i + srs_pdu->bwp_start; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 96cad0f3c3..af485fd848 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -94,7 +94,8 @@ static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac, frame_t frame, slot_t slot, pucch->csi_bits, pucch->dai_c, pucch->sr_flag, - pucch->r_pucch); + pucch->r_pucch, + nrmac->beam_info.beam_mode); } #define MIN_RSRP_VALUE -141 @@ -253,9 +254,10 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, slot_t slot) "Only periodic CSI reporting is implemented currently\n"); const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0]; - if(pucchcsires->uplinkBandwidthPartId != ul_bwp->bwp_id) + if(pucchcsires->uplinkBandwidthPartId > 1) { + LOG_E(NR_MAC, "Invalid PUCCH BWP ID %ld, we only configure BWP up to 1\n", pucchcsires->uplinkBandwidthPartId); continue; - + } // we schedule CSI reporting max_fb_time slots in advance int period, offset; csi_period_offset(csirep, NULL, &period, &offset); @@ -279,7 +281,10 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, slot_t slot) const int pucch_index = get_pucch_index(sched_frame, sched_slot, &nrmac->frame_structure, sched_ctrl->sched_pucch_size); NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index]; - AssertFatal(curr_pucch->active == false, "CSI structure is scheduled in advance. It should be free!\n"); + if (curr_pucch->active) { + LOG_E(NR_MAC, "CSI structure is scheduled in advance. It should be free!\n"); + memset(curr_pucch, 0, sizeof(*curr_pucch)); + } curr_pucch->r_pucch = -1; curr_pucch->frame = sched_frame; curr_pucch->ul_slot = sched_slot; @@ -393,16 +398,15 @@ int get_pucch_resourceid(NR_PUCCH_Config_t *pucch_Config, int O_uci, int pucch_r return *resource_id; } -static void handle_dl_harq(NR_UE_info_t * UE, - int8_t harq_pid, - bool success, - int harq_round_max) +static void handle_dl_harq(gNB_MAC_INST *mac, NR_UE_info_t * UE, int8_t harq_pid, bool success, int harq_round_max) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid]; harq->feedback_slot = -1; harq->is_waiting = false; if (success) { + if (harq->sched_pdsch.action) + harq->sched_pdsch.action(mac, UE); finish_nr_dl_harq(sched_ctrl, harq_pid); } else if (harq->round >= harq_round_max - 1) { abort_nr_dl_harq(UE, harq_pid); @@ -749,7 +753,6 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR reportQuantity_type_r16 = NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_NOTHING; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; const int n_slots_frame = nrmac->frame_structure.numb_slots_frame; int cumul_bits = 0; @@ -764,8 +767,10 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_CSI_ReportConfig_t *csirep = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; uint8_t cqi_table = (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_1 && csirep->cqi_Table) ? *csirep->cqi_Table : NR_CSI_ReportConfig__cqi_Table_table1; const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0]; - if(pucchcsires->uplinkBandwidthPartId != ul_bwp->bwp_id) + if(pucchcsires->uplinkBandwidthPartId > 1) { + LOG_E(NR_MAC, "Invalid PUCCH BWP ID %ld, we only configure BWP up to 1\n", pucchcsires->uplinkBandwidthPartId); continue; + } int period, offset; csi_period_offset(csirep, NULL, &period, &offset); // verify if report with current id has been scheduled for this frame and slot @@ -873,7 +878,7 @@ static NR_UE_harq_t *find_harq(frame_t frame, slot_t slot, NR_UE_info_t * UE, in frame, slot); remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - handle_dl_harq(UE, pid, 0, harq_round_max); + handle_dl_harq(NULL, UE, pid, false, harq_round_max); pid = sched_ctrl->feedback_dl_harq.head; if (pid < 0) return NULL; @@ -930,7 +935,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, frame_t frame, slot_t slot, con LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value); nr_mac_update_pdcch_closed_loop_adjust(sched_ctrl, harq_confidence != 0); bool success = harq_value == 0 && harq_confidence == 0; - handle_dl_harq(UE, pid, success, nrmac->dl_bler.harq_round_max); + handle_dl_harq(nrmac, UE, pid, success, nrmac->dl_bler.harq_round_max); if (is_ra) { bool ue_rejected = nr_check_Msg4_MsgB_Ack(mod_id, frame, slot, UE, success); if (ue_rejected) { @@ -976,11 +981,6 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, frame_t frame, slot_t slot, c return; } - NR_CSI_MeasConfig_t *csi_MeasConfig = UE->sc_info.csi_MeasConfig; - if (csi_MeasConfig == NULL) { - NR_SCHED_UNLOCK(&nrmac->sched_lock); - return; - } NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; // tpc (power control) @@ -1009,15 +1009,18 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, frame_t frame, slot_t slot, c const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit, pid, acknack); - handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max); + handle_dl_harq(nrmac, UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max); } free(uci_234->harq.harq_payload); } if ((uci_234->pduBitmap >> 2) & 0x01) { LOG_D(NR_MAC, "CSI CRC %d\n", uci_234->csi_part1.csi_part1_crc); if (uci_234->csi_part1.csi_part1_crc != 1) { - // API to parse the csi report and store it into sched_ctrl - extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE, nrmac); + NR_CSI_MeasConfig_t *csi_MeasConfig = UE->sc_info.csi_MeasConfig; + if (csi_MeasConfig != NULL) { + // API to parse the csi report and store it into sched_ctrl + extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE, nrmac); + } } free(uci_234->csi_part1.csi_part1_payload); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 9d9000245e..6ff8ecefe6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -163,7 +163,8 @@ bwp_info_t get_pusch_bwp_start_size(NR_UE_info_t *UE) // contiguously allocated non-interleaved virtual resource blocks within the active bandwidth part of size PRBs except for the // case when DCI format 0_0 is decoded in any common search space in which case the size of the initial UL bandwidth part shall // be used. - if (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_0 && sched_ctrl->search_space->searchSpaceType + if (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_0 + && sched_ctrl->search_space->searchSpaceType && sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) { bwp_info.bwpSize = min(ul_bwp->BWPSize, UE->sc_info.initial_ul_BWPSize); } else { @@ -772,10 +773,9 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, nr_mac_reset_ul_failure(sched_ctrl); reset_dl_harq_list(sched_ctrl); reset_ul_harq_list(sched_ctrl); - // we configure the UE using common search space with DCIX0 while waiting for a reconfiguration in SA - // in NSA (or do-ra) there is no reconfiguration in NR - int ss_type = IS_SA_MODE(get_softmodem_params()) ? NR_SearchSpace__searchSpaceType_PR_common - : NR_SearchSpace__searchSpaceType_PR_ue_Specific; + // we configure the UE using dedicated search space: In SA (CFRA used for + // handover) and NSA (or do-ra), the UE has the full config already. + int ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific; configure_UE_BWP(mac, scc, UE, false, ss_type, -1, -1); // initialize ta_frame in case there is no Msg3 received UE->UE_sched_ctrl.ta_frame = (frame + 100) % MAX_FRAME_NUMBER; @@ -882,7 +882,7 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, // Only trigger RRCReconfiguration if UE is not performing RRCReestablishment // The RRCReconfiguration will be triggered by the RRCReestablishmentComplete - if (!old_UE->reconfigSpCellConfig) { + if (!old_UE->reconfigCellGroup) { LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", crnti); // Trigger RRCReconfiguration nr_mac_trigger_reconfiguration(mac, old_UE, -1); @@ -2318,7 +2318,8 @@ nfapi_nr_pusch_pdu_t *prepare_pusch_pdu(nfapi_nr_ul_tti_request_t *future_ul_tti int harq_id, int harq_round, int fh, - int rnti) + int rnti, + nr_beam_mode_t beam_mode) { nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu; memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); @@ -2368,7 +2369,8 @@ nfapi_nr_pusch_pdu_t *prepare_pusch_pdu(nfapi_nr_ul_tti_request_t *future_ul_tti pusch_pdu->beamforming.num_prgs = 1; pusch_pdu->beamforming.prg_size = pusch_pdu->bwp_size; pusch_pdu->beamforming.dig_bf_interface = 1; - pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; + pusch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = + convert_to_fapi_beam(UE->UE_beam_index, beam_mode); /* TRANSFORM PRECODING --------------------------------------------------------*/ if (pusch_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) { // U as specified in section 6.4.1.1.1.2 in 38.211, if sequence hopping and group hopping are disabled @@ -2526,7 +2528,8 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE harq_id, cur_harq->round, current_BWP->pusch_Config && current_BWP->pusch_Config->frequencyHopping, - UE->rnti); + UE->rnti, + nr_mac->beam_info.beam_mode); req->n_pdus += 1; // Calculate the normalized tx_power for PHR @@ -2568,7 +2571,7 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE coreset, sched_ctrl->aggregation_level, sched_ctrl->cce_index, - UE->UE_beam_index, + convert_to_fapi_beam(UE->UE_beam_index, nr_mac->beam_info.beam_mode), UE->rnti); pdcch_pdu->numDlDci++; @@ -2610,7 +2613,6 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE &uldci_payload, current_BWP->dci_format, TYPE_C_RNTI_, - current_BWP->bwp_id, ss, coreset, UE->pdsch_HARQ_ACK_Codebook, diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_config.h b/openair2/LAYER2/NR_MAC_gNB/mac_config.h index 1fdbe62115..6089d39975 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_config.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_config.h @@ -43,4 +43,6 @@ typedef struct gnb_sat_position_update_s { bool nr_update_sib19(const gnb_sat_position_update_t *sat_position); +bool nr_trigger_bwp_switch(uint16_t rnti, int bwp_id); + #endif /*__LAYER2_NR_MAC_CONFIG_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 373ea2be4b..25fb1e828f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -213,14 +213,15 @@ int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset, NR_PUCCH_Config_t *pucch_Config, int CCEIndex); -void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, +void nr_configure_pucch(nfapi_nr_pucch_pdu_t *pucch_pdu, NR_ServingCellConfigCommon_t *scc, - NR_UE_info_t* UE, + NR_UE_info_t *UE, uint8_t pucch_resource, uint16_t O_csi, uint16_t O_ack, uint8_t O_sr, - int r_pucch); + int r_pucch, + nr_beam_mode_t mode); void find_search_space(int ss_type, NR_BWP_Downlink_t *bwp, @@ -258,7 +259,6 @@ void fill_dci_pdu_rel15(const NR_UE_ServingCell_Info_t *servingCellInfo, dci_pdu_rel15_t *dci_pdu_rel15, int dci_format, int rnti_type, - int bwp_id, NR_SearchSpace_t *ss, NR_ControlResourceSet_t *coreset, long pdsch_HARQ_ACK_Codebook, @@ -331,7 +331,8 @@ nfapi_nr_pusch_pdu_t *prepare_pusch_pdu(nfapi_nr_ul_tti_request_t *future_ul_tti int harq_id, int harq_round, int fh, - int rnti); + int rnti, + nr_beam_mode_t beam_mode); nfapi_nr_dl_tti_pdsch_pdu_rel15_t *prepare_pdsch_pdu(nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu, const gNB_MAC_INST *mac, const NR_UE_info_t *UE, @@ -446,10 +447,14 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options, int ul_buffer_index(int frame, int slot, int slots_per_frame, int size); void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP); -void fapi_beam_index_allocation(NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config, gNB_MAC_INST *mac); -int get_fapi_beamforming_index(gNB_MAC_INST *mac, int ssb_idx); -NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame); -void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int beam_index, int slots_per_frame, bool new_beam); +uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc); +uint64_t get_ssb_bitmap_and_len(const NR_ServingCellConfigCommon_t *scc, uint8_t *len); +void fill_beam_index_list(NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config, gNB_MAC_INST *mac); +int get_beam_from_ssbidx(gNB_MAC_INST *mac, int ssb_idx); +int16_t get_allocated_beam(const NR_beam_info_t *beam_info, int frame, int slot, int slots_per_frame, int beam_number_in_period); +uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode); +NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame); +void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, bool new_beam); void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE); void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, slot_t slotP); bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE); @@ -478,7 +483,7 @@ void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpac void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl); bool nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl); -void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE, int new_bwp_id); +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id); bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c); nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 92b2b2c6fc..d9450f0ff0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -608,6 +608,7 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id, const NR_C cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc, mac->frame); // TODO: in NSA we assign capabilities here, otherwise outside => not logic UE->capability = cap; + UE->local_bwp_id = 1; // get_default_secondaryCellGroup sets 1st active BWP as 1 } // note: we don't pass the cellGroupConfig to add_new_nr_ue() because we need // the uid to create the CellGroupConfig (which is in the UE context created @@ -726,8 +727,8 @@ void ue_context_setup_request(const f1ap_ue_context_setup_req_t *req) cgc.len = (enc_rval.encoded + 7) >> 3; resp.du_to_cu_rrc_info.cell_group_config = cgc; - ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); - UE->CellGroup = new_CellGroup; + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup); + UE->reconfigCellGroup = new_CellGroup; int ss_type = cg_configinfo ? NR_SearchSpace__searchSpaceType_PR_ue_Specific: NR_SearchSpace__searchSpaceType_PR_common; configure_UE_BWP(mac, scc, UE, false, ss_type, -1, -1); @@ -801,16 +802,19 @@ void ue_context_modification_request(const f1ap_ue_context_mod_req_t *req) "RRC reconfiguration outcome unsuccessful, but no rollback mechanism implemented to come back to old configuration\n"); } else if (req->reconfig_compl) { LOG_I(NR_MAC, "DU received confirmation of successful RRC Reconfiguration\n"); - if (UE->reconfigSpCellConfig) { - // in case of reestablishment, the spCellConfig had to be released - // temporarily. Reapply now before doing the reconfiguration. - UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig; - UE->reconfigSpCellConfig = NULL; + if (UE->reconfigCellGroup) { + LOG_W(NR_MAC, "reconfigCellGroup still present, did we miss ACK for RRCReconfiguration?\n"); + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); + UE->CellGroup = UE->reconfigCellGroup; + UE->reconfigCellGroup = NULL; + } + if (UE->reestablish_rlc) { for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) { nr_lc_config_t *c = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i); c->suspended = false; nr_rlc_reestablish_entity(req->gNB_DU_ue_id, c->lcid); } + UE->reestablish_rlc = false; } // we re-configure the BWP to apply the CellGroup and to use UE specific Search Space with DCIX1 configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_ue_Specific, -1, -1); @@ -837,8 +841,8 @@ void ue_context_modification_request(const f1ap_ue_context_mod_req_t *req) cgc.len = (enc_rval.encoded + 7) >> 3; resp.du_to_cu_rrc_info->cell_group_config = cgc; - ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); - UE->CellGroup = new_CellGroup; + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->reconfigCellGroup); + UE->reconfigCellGroup = new_CellGroup; configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); } else { ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, new_CellGroup); // we actually don't need it @@ -916,6 +920,7 @@ void ue_context_release_command(const f1ap_ue_context_rel_cmd_t *cmd) UE = UE ? UE : find_ra_UE(&mac->UE_info, cmd->gNB_DU_ue_id); if (UE == NULL) { NR_SCHED_UNLOCK(&mac->sched_lock); + LOG_W(NR_MAC, "UE Context Release Command for unknown RNTI %04x/CU UE ID %d\n", cmd->gNB_DU_ue_id, cmd->gNB_CU_ue_id); f1ap_ue_context_rel_cplt_t complete = { .gNB_CU_ue_id = cmd->gNB_CU_ue_id, .gNB_DU_ue_id = cmd->gNB_DU_ue_id, @@ -994,15 +999,19 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = oldUE->CellGroup; oldUE->CellGroup = NULL; + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability); UE->capability = oldUE->capability; oldUE->capability = NULL; UE->mac_stats = oldUE->mac_stats; UE->measgap_config = oldUE->measgap_config; + UE->local_bwp_id = oldUE->local_bwp_id; /* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it * from the current configuration. It will be reapplied when the * reconfiguration has succeeded (indicated by the CU) */ - UE->reconfigSpCellConfig = UE->CellGroup->spCellConfig; + asn_copy(&asn_DEF_NR_CellGroupConfig, (void **)&UE->reconfigCellGroup, UE->CellGroup); + ASN_STRUCT_FREE(asn_DEF_NR_SpCellConfig, UE->CellGroup->spCellConfig); UE->CellGroup->spCellConfig = NULL; + UE->reestablish_rlc = true; mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id); pthread_mutex_unlock(&mac->sched_lock); nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index f3f070b0e7..7b32665717 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -302,7 +302,8 @@ void mac_top_init_gNB(ngran_node_t node_type, RC.nrmac[i]->tag = (NR_TAG_t*)malloc(sizeof(NR_TAG_t)); memset((void*)RC.nrmac[i]->tag,0,sizeof(NR_TAG_t)); - + for(int n = 0; n < MAX_NUM_OF_SSB; n++) + RC.nrmac[i]->sib1_pdsch[n].time_domain_allocation = -1; RC.nrmac[i]->common_channels[0].ServingCellConfigCommon = scc; RC.nrmac[i]->radio_config = *config; RC.nrmac[i]->rlc_config = *default_rlc_config; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 2914eea915..d8e512b0fb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -187,7 +187,6 @@ typedef enum { } nr_config_report_type_t; typedef struct nr_mac_config_t { - int sib1_tda; nr_pdsch_AntennaPorts_t pdsch_AntennaPorts; int pusch_AntennaPorts; int minRXTXTIME; @@ -320,7 +319,7 @@ typedef struct { //Total available prach occasions int total_prach_occasions; //Max Association period - int max_association_period; + int association_period; //SSB index uint8_t ssb_index[MAX_NUM_OF_SSB]; //CB preambles for each SSB @@ -476,6 +475,9 @@ typedef struct NR_pdsch_dmrs { NR_PTRS_DownlinkConfig_t *phaseTrackingRS; } NR_pdsch_dmrs_t; +struct NR_UE_info; +struct gNB_MAC_INST_s; +typedef void (*feedback_action_t)(struct gNB_MAC_INST_s *mac, struct NR_UE_info *ue); typedef struct NR_sched_pdsch { /// RB allocation within active BWP uint16_t rbSize; @@ -502,6 +504,7 @@ typedef struct NR_sched_pdsch { // time_domain_allocation is the index of a list of tda int time_domain_allocation; NR_tda_info_t tda_info; + feedback_action_t action; } NR_sched_pdsch_t; typedef struct NR_UE_harq { @@ -773,7 +776,7 @@ typedef struct measgap_config { } measgap_config_t; /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ -typedef struct { +typedef struct NR_UE_info { rnti_t rnti; uid_t uid; // unique ID of this UE /// scheduling control info @@ -785,18 +788,23 @@ typedef struct { NR_mac_stats_t mac_stats; /// currently active CellGroupConfig NR_CellGroupConfig_t *CellGroup; - /// in case of reestablishment, old spCellConfig to apply after - /// reconfiguration - NR_SpCellConfig_t *reconfigSpCellConfig; + /// in case of reconfiguration, new CellConfig to apply + NR_CellGroupConfig_t *reconfigCellGroup; NR_UE_NR_Capability_t *capability; measgap_config_t measgap_config; // UE selected beam index - uint8_t UE_beam_index; + uint16_t UE_beam_index; float ul_thr_ue; float dl_thr_ue; long pdsch_HARQ_ACK_Codebook; bool is_redcap; + bool reestablish_rlc; NR_RA_t *ra; + // 3GPP mandates that BWPs are enumerated consecutively, but we only send one (dedicated) + // BWP to the UE (and modify that BWP on reconfiguration); consequently, the BWP ID for a + // dedicated BWP is always 1 from the UE's point of view, even if the gNB has multiple BWPs. + // The below ID is the "true" (non-consecutive) BWP ID from the gNB's point of view + NR_BWP_Id_t local_bwp_id; } NR_UE_info_t; typedef struct { @@ -817,7 +825,7 @@ typedef enum { typedef struct { /// list of allocated beams per period - int **beam_allocation; + int16_t **beam_allocation; int beam_duration; // in slots int beams_per_period; int beam_allocation_size; @@ -988,7 +996,8 @@ typedef struct gNB_MAC_INST_s { uint16_t min_grant_prb; bool identity_pm; int precoding_matrix_size[NR_MAX_NB_LAYERS]; - int fapi_beam_index[MAX_NUM_OF_SSB]; + int beam_index_list[MAX_NUM_OF_SSB]; + NR_sched_pdsch_t sib1_pdsch[MAX_NUM_OF_SSB]; /// dedicate UL TDA, common for all UEs seq_arr_t ul_tda; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index a9e53b6d32..6f80db9b6d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -273,21 +273,23 @@ NR_SearchSpace_t *rrc_searchspace_config(bool is_common, return ss; } -static NR_ControlResourceSet_t *get_coreset_config(int bwp_id, int curr_bwp, uint64_t ssb_bitmap) +static NR_ControlResourceSet_t *get_coreset_config(int bwp_id, int bwp_start, int bwp_size, uint64_t ssb_bitmap) { NR_ControlResourceSet_t *coreset = calloc(1, sizeof(*coreset)); AssertFatal(coreset != NULL, "out of memory\n"); // frequency domain resources depending on BWP size + int additional_offset = (bwp_start + 5) / 6 * 6 - bwp_start; + int eff_bwp_size = bwp_size - additional_offset; coreset->frequencyDomainResources.buf = calloc(1,6); - coreset->frequencyDomainResources.buf[0] = (curr_bwp < 48) ? 0xf0 : 0xff; - coreset->frequencyDomainResources.buf[1] = (curr_bwp < 96) ? 0x00 : 0xff; - coreset->frequencyDomainResources.buf[2] = (curr_bwp < 144) ? 0x00 : 0xff; - coreset->frequencyDomainResources.buf[3] = (curr_bwp < 192) ? 0x00 : 0xff; - coreset->frequencyDomainResources.buf[4] = (curr_bwp < 240) ? 0x00 : 0xff; + coreset->frequencyDomainResources.buf[0] = (eff_bwp_size < 48) ? 0xf0 : 0xff; + coreset->frequencyDomainResources.buf[1] = (eff_bwp_size < 96) ? 0x00 : 0xff; + coreset->frequencyDomainResources.buf[2] = (eff_bwp_size < 144) ? 0x00 : 0xff; + coreset->frequencyDomainResources.buf[3] = (eff_bwp_size < 192) ? 0x00 : 0xff; + coreset->frequencyDomainResources.buf[4] = (eff_bwp_size < 240) ? 0x00 : 0xff; coreset->frequencyDomainResources.buf[5] = 0x00; coreset->frequencyDomainResources.size = 6; coreset->frequencyDomainResources.bits_unused = 3; - coreset->duration = (curr_bwp < 48) ? 2 : 1; + coreset->duration = (eff_bwp_size < 48) ? 2 : 1; coreset->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved; coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; @@ -309,7 +311,7 @@ static NR_ControlResourceSet_t *get_coreset_config(int bwp_id, int curr_bwp, uin return coreset; } -static uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc) +uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc) { uint64_t bitmap=0; switch (scc->ssb_PositionsInBurst->present) { @@ -1505,10 +1507,38 @@ static NR_PTRS_UplinkConfig_t *config_ulptrs(const nr_ptrs_config_t *ptrs) return ulptrs; } -static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS, +long ue_supported_ul_layers(const NR_UE_NR_Capability_t *uecap) +{ + long ul_max_layers = 1; + if (uecap + && uecap->featureSets + && uecap->featureSets->featureSetsUplinkPerCC + && uecap->featureSets->featureSetsUplinkPerCC->list.count > 0) { + NR_FeatureSetUplinkPerCC_t *ul_feature_setup_per_cc = uecap->featureSets->featureSetsUplinkPerCC->list.array[0]; + if (ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) { + switch (*ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) { + case NR_MIMO_LayersUL_twoLayers: + ul_max_layers = 2; + break; + case NR_MIMO_LayersUL_fourLayers: + ul_max_layers = 4; + break; + default: + ul_max_layers = 1; + } + } + } + return ul_max_layers; +} + +static long set_ul_max_layers(const nr_mac_config_t *configuration, const NR_UE_NR_Capability_t *uecap) +{ + return min(ue_supported_ul_layers(uecap), configuration->pusch_AntennaPorts); +} + +static NR_SetupRelease_PUSCH_Config_t *config_pusch(const nr_mac_config_t *configuration, const NR_ServingCellConfigCommon_t *scc, - const NR_UE_NR_Capability_t *uecap, - const nr_ptrs_config_t *ptrs) + const NR_UE_NR_Capability_t *uecap) { NR_SetupRelease_PUSCH_Config_t *setup_puschconfig = calloc(1, sizeof(*setup_puschconfig)); setup_puschconfig->present = NR_SetupRelease_PUSCH_Config_PR_setup; @@ -1526,8 +1556,8 @@ static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS, if (!pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup) pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup = calloc(1, sizeof(*pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup)); NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; - if (ptrs) { - NR_PTRS_UplinkConfig_t *ptrs_config = config_ulptrs(ptrs); + if (configuration->ptrs) { + NR_PTRS_UplinkConfig_t *ptrs_config = config_ulptrs(configuration->ptrs); NR_SetupRelease_PTRS_UplinkConfig_t *phaseTrackingRS = calloc(1, sizeof(*phaseTrackingRS)); phaseTrackingRS->present = NR_SetupRelease_PTRS_UplinkConfig_PR_setup; phaseTrackingRS->choice.setup = ptrs_config; @@ -1569,7 +1599,7 @@ static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS, asn1cSeqAdd(&pusch_Config->pusch_PowerControl->pathlossReferenceRSToAddModList->list, plrefRS); pusch_Config->pusch_PowerControl->pathlossReferenceRSToReleaseList = NULL; pusch_Config->pusch_PowerControl->twoPUSCH_PC_AdjustmentStates = NULL; - if (use_deltaMCS) { + if (configuration->use_deltaMCS) { if (!pusch_Config->pusch_PowerControl->deltaMCS) pusch_Config->pusch_PowerControl->deltaMCS = calloc(1, sizeof(*pusch_Config->pusch_PowerControl->deltaMCS)); *pusch_Config->pusch_PowerControl->deltaMCS = NR_PUSCH_PowerControl__deltaMCS_enabled; @@ -1582,14 +1612,14 @@ static NR_SetupRelease_PUSCH_Config_t *config_pusch(const bool use_deltaMCS, pusch_Config->resourceAllocation = NR_PUSCH_Config__resourceAllocation_resourceAllocationType1; pusch_Config->pusch_TimeDomainAllocationList = NULL; pusch_Config->pusch_AggregationFactor = NULL; - set_ul_mcs_table(uecap, scc, pusch_Config); + set_ul_mcs_table(configuration->force_UL256qam_off ? NULL : uecap, scc, pusch_Config); pusch_Config->transformPrecoder = NULL; if (!pusch_Config->codebookSubset) pusch_Config->codebookSubset = calloc(1, sizeof(*pusch_Config->codebookSubset)); *pusch_Config->codebookSubset = NR_PUSCH_Config__codebookSubset_nonCoherent; if (!pusch_Config->maxRank) pusch_Config->maxRank = calloc(1, sizeof(*pusch_Config->maxRank)); - *pusch_Config->maxRank = 1; + *pusch_Config->maxRank = set_ul_max_layers(configuration, uecap); pusch_Config->rbg_Size = NULL; pusch_Config->uci_OnPUSCH = NULL; pusch_Config->tp_pi2BPSK = NULL; @@ -1696,20 +1726,18 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t const NR_UE_NR_Capability_t *uecap, int dl_antenna_ports, bool force_256qam_off, - int bwp_loop, bool is_SA, const nr_mac_config_t *configuration) { NR_BWP_Downlink_t *bwp = calloc_or_fail(1, sizeof(*bwp)); + bwp->bwp_Id = 1; bwp->bwp_Common = calloc(1,sizeof(*bwp->bwp_Common)); - if(configuration->num_additional_bwps > 0) { - const nr_bwp_config_t *bwp_config = &configuration->bwp_config[bwp_loop]; - bwp->bwp_Id = bwp_config->id; + if(configuration->num_additional_bwps > 0 && configuration->first_active_bwp > 0) { + const nr_bwp_config_t *bwp_config = &configuration->bwp_config[configuration->first_active_bwp - 1]; bwp->bwp_Common->genericParameters.locationAndBandwidth = bwp_config->location_and_bw; bwp->bwp_Common->genericParameters.subcarrierSpacing = bwp_config->scs; bwp->bwp_Common->genericParameters.cyclicPrefix = NULL; } else { - bwp->bwp_Id=bwp_loop+1; bwp->bwp_Common->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,0); bwp->bwp_Common->genericParameters.subcarrierSpacing = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; bwp->bwp_Common->genericParameters.cyclicPrefix = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix; @@ -1720,10 +1748,10 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t bwp->bwp_Common->pdcch_ConfigCommon->choice.setup = calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup)); bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero = NULL; - int curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); - + int bwp_size = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bwp_start = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); uint64_t ssb_bitmap = get_ssb_bitmap(scc); - NR_ControlResourceSet_t *coreset = get_coreset_config(bwp->bwp_Id, curr_bwp, ssb_bitmap); + NR_ControlResourceSet_t *coreset = get_coreset_config(bwp->bwp_Id, bwp_start, bwp_size, ssb_bitmap); bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = coreset; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL; @@ -1743,7 +1771,7 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t agg_level_candidates[PDCCH_AGG_LEVEL4] = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; agg_level_candidates[PDCCH_AGG_LEVEL8] = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; agg_level_candidates[PDCCH_AGG_LEVEL16] = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; - ss = rrc_searchspace_config(true, searchspaceid, 0, agg_level_candidates); + ss = rrc_searchspace_config(true, searchspaceid, coreset->controlResourceSetId, agg_level_candidates); } asn1cSeqAdd(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss); @@ -1764,7 +1792,7 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t nr_rrc_config_dl_tda(bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList, get_frame_type((int)*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing), scc->tdd_UL_DL_ConfigurationCommon, - curr_bwp); + bwp_size); if (!bwp->bwp_Dedicated) { bwp->bwp_Dedicated=calloc(1,sizeof(*bwp->bwp_Dedicated)); @@ -1777,14 +1805,14 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t // coreset2 is identical to coreset above, but reallocated to prevent double // frees - NR_ControlResourceSet_t *coreset2 = get_coreset_config(bwp->bwp_Id, curr_bwp, ssb_bitmap); + NR_ControlResourceSet_t *coreset2 = get_coreset_config(bwp->bwp_Id, bwp_start, bwp_size, ssb_bitmap); asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, coreset2); int rrc_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; int num_cces = get_coreset_num_cces(coreset2->frequencyDomainResources.buf, coreset2->duration); verify_agg_levels(num_cces, configuration->num_agg_level_candidates, coreset2->controlResourceSetId, rrc_num_agg_level_candidates); searchspaceid = 10 + bwp->bwp_Id; - NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, searchspaceid, is_SA ? 0 : coreset2->controlResourceSetId, agg_level_candidates); + NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, searchspaceid, coreset2->controlResourceSetId, agg_level_candidates); asn1cSeqAdd(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2); searchspaceid = 20 + bwp->bwp_Id; @@ -1802,8 +1830,7 @@ static NR_BWP_Downlink_t *config_downlinkBWP(const NR_ServingCellConfigCommon_t return bwp; } -static NR_BWP_Uplink_t *config_uplinkBWP(long bwp_loop, - bool is_SA, +static NR_BWP_Uplink_t *config_uplinkBWP(bool is_SA, int uid, int maxMIMO_Layers, const nr_mac_config_t *configuration, @@ -1811,14 +1838,14 @@ static NR_BWP_Uplink_t *config_uplinkBWP(long bwp_loop, const NR_UE_NR_Capability_t *uecap) { NR_BWP_Uplink_t *ubwp = calloc_or_fail(1, sizeof(*ubwp)); + ubwp->bwp_Id = 1; ubwp->bwp_Common = calloc(1, sizeof(*ubwp->bwp_Common)); - if(configuration->num_additional_bwps > 0) { - ubwp->bwp_Id = configuration->bwp_config[bwp_loop].id; - ubwp->bwp_Common->genericParameters.locationAndBandwidth = configuration->bwp_config[bwp_loop].location_and_bw; - ubwp->bwp_Common->genericParameters.subcarrierSpacing = configuration->bwp_config[bwp_loop].scs; + if(configuration->num_additional_bwps > 0 && configuration->first_active_bwp > 0) { + int bwp_idx = configuration->first_active_bwp - 1; + ubwp->bwp_Common->genericParameters.locationAndBandwidth = configuration->bwp_config[bwp_idx].location_and_bw; + ubwp->bwp_Common->genericParameters.subcarrierSpacing = configuration->bwp_config[bwp_idx].scs; ubwp->bwp_Common->genericParameters.cyclicPrefix = NULL; } else { - ubwp->bwp_Id=bwp_loop+1; ubwp->bwp_Common->genericParameters.locationAndBandwidth = PRBalloc_to_locationandbandwidth(scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth,0); ubwp->bwp_Common->genericParameters.subcarrierSpacing = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; ubwp->bwp_Common->genericParameters.cyclicPrefix = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.cyclicPrefix; @@ -1855,16 +1882,13 @@ static NR_BWP_Uplink_t *config_uplinkBWP(long bwp_loop, scheduling_request_config(scc, pucch_Config, ubwp->bwp_Common->genericParameters.subcarrierSpacing); set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, ubwp->bwp_Common->genericParameters.subcarrierSpacing); - ubwp->bwp_Dedicated->pusch_Config = config_pusch(configuration->use_deltaMCS, - scc, - configuration->force_UL256qam_off ? NULL : uecap, - configuration->ptrs); + ubwp->bwp_Dedicated->pusch_Config = config_pusch(configuration, scc, uecap); ubwp->bwp_Dedicated->srs_Config = get_config_srs(scc, NULL, curr_bwp, uid, - bwp_loop + 1, + ubwp->bwp_Id, maxMIMO_Layers, configuration->minRXTXTIME, configuration->do_SRS); @@ -3268,6 +3292,7 @@ static void fill_harq_IEs(NR_ServingCellConfig_t *scc, int num_dlharq, int num_u static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *configuration, int maxMIMO_Layers, + const NR_UE_NR_Capability_t *uecap, int id) { NR_BWP_UplinkDedicated_t *initialUplinkBWP = calloc(1, sizeof(*initialUplinkBWP)); @@ -3282,14 +3307,14 @@ static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellCo pucch_Config->resourceToAddModList = calloc(1, sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); - config_pucch_resset0(pucch_Config, id, curr_bwp, num_pucch2, NULL); - config_pucch_resset1(pucch_Config, id, num_pucch2, NULL); + config_pucch_resset0(pucch_Config, id, curr_bwp, num_pucch2, uecap); + config_pucch_resset1(pucch_Config, id, num_pucch2, uecap); set_pucch_power_config(pucch_Config, configuration->do_CSIRS); - initialUplinkBWP->pusch_Config = config_pusch(configuration->use_deltaMCS, scc, NULL, configuration->ptrs); + initialUplinkBWP->pusch_Config = config_pusch(configuration, scc, uecap); // We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1 - initialUplinkBWP->srs_Config = get_config_srs(scc, NULL, curr_bwp, id, 0, maxMIMO_Layers, configuration->minRXTXTIME, 0); + initialUplinkBWP->srs_Config = get_config_srs(scc, uecap, curr_bwp, id, 0, maxMIMO_Layers, configuration->minRXTXTIME, 0); scheduling_request_config(scc, pucch_Config, scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing); set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, genericParameters->subcarrierSpacing); @@ -3299,6 +3324,7 @@ static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellCo static NR_BWP_DownlinkDedicated_t *configure_initial_dl_bwp(const NR_ServingCellConfigCommon_t *scc, const int pdsch_AntennaPorts, uint64_t bitmap, + const NR_UE_NR_Capability_t *uecap, const nr_mac_config_t *configuration) { NR_BWP_DownlinkDedicated_t *bwp_Dedicated = calloc(1, sizeof(*bwp_Dedicated)); @@ -3308,8 +3334,9 @@ static NR_BWP_DownlinkDedicated_t *configure_initial_dl_bwp(const NR_ServingCell pdcch_Config->searchSpacesToAddModList = calloc(1, sizeof(*pdcch_Config->searchSpacesToAddModList)); pdcch_Config->controlResourceSetToAddModList = calloc(1, sizeof(*pdcch_Config->controlResourceSetToAddModList)); NR_BWP_t *genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - int curr_bwp = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - NR_ControlResourceSet_t *coreset = get_coreset_config(0, curr_bwp, bitmap); + int bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + NR_ControlResourceSet_t *coreset = get_coreset_config(0, bwp_start, bwp_size, bitmap); asn1cSeqAdd(&pdcch_Config->controlResourceSetToAddModList->list, coreset); int css_num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; @@ -3330,6 +3357,11 @@ static NR_BWP_DownlinkDedicated_t *configure_initial_dl_bwp(const NR_ServingCell bwp_Dedicated->pdcch_Config->choice.setup = pdcch_Config; bwp_Dedicated->pdsch_Config = config_pdsch(bitmap, 0, pdsch_AntennaPorts, configuration->ptrs); + // we might call configuration of initial BWP for BWP switch when we already have UE capabilities + set_dl_mcs_table(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing, + configuration->force_256qam_off ? NULL : uecap, + bwp_Dedicated, + scc); return bwp_Dedicated; } @@ -3367,10 +3399,14 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf pdsch_Config = configDedicated->initialDownlinkBWP->pdsch_Config; curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); } else { - NR_BWP_Downlink_t *bwp = configDedicated->downlinkBWP_ToAddModList->list.array[0]; + NR_BWP_Downlink_t *bwp = NULL; + for (int i = 0; i < configDedicated->downlinkBWP_ToAddModList->list.count; i++) { + if (bwp_id == configDedicated->downlinkBWP_ToAddModList->list.array[i]->bwp_Id) + bwp = configDedicated->downlinkBWP_ToAddModList->list.array[i]; + } + AssertFatal(bwp, "BWP ID doesn't match\n"); pdsch_Config = bwp->bwp_Dedicated->pdsch_Config; curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - AssertFatal(bwp_id == bwp->bwp_Id, "BWP ID doesn't match\n"); } const int pdsch_AntennaPorts = @@ -3484,42 +3520,28 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, asn1cCallocOne(pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH, NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n16); pdsch_servingcellconfig->pucch_Cell = NULL; set_dl_maxmimolayers(pdsch_servingcellconfig, scc, NULL, configuration->maxMIMO_layers); - if (configuration->disable_harq) { - if (!pdsch_servingcellconfig->ext3) - pdsch_servingcellconfig->ext3 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3)); - pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17)); - pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->present = NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_setup; - pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf = calloc(4, sizeof(uint8_t)); - pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.size = 4; - pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.bits_unused = 0; - pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[0] = 0xFF; - pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[1] = 0xFF; - pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[2] = 0xFF; - pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[3] = 0xFF; - } uint64_t bitmap = get_ssb_bitmap(scc); int first_active_bwp = 0; if (configuration->num_additional_bwps > 0) - first_active_bwp = configuration->first_active_bwp; + first_active_bwp = configuration->first_active_bwp > 0 ? 1 : 0; asn1cCallocOne(configDedicated->firstActiveDownlinkBWP_Id, first_active_bwp); asn1cCallocOne(uplinkConfig->firstActiveUplinkBWP_Id, first_active_bwp); if (first_active_bwp == 0) { - uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, maxMIMO_Layers, uid); - configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, configuration); + uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, maxMIMO_Layers, NULL, uid); + configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, NULL, configuration); } else { configDedicated->downlinkBWP_ToAddModList = calloc(1, sizeof(*configDedicated->downlinkBWP_ToAddModList)); NR_BWP_Downlink_t *bwp = config_downlinkBWP(scc, NULL, 0, false, - first_active_bwp - 1, true, configuration); asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, bwp); uplinkConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*uplinkConfig->uplinkBWP_ToAddModList)); - NR_BWP_Uplink_t *ubwp = config_uplinkBWP(first_active_bwp - 1, true, uid, maxMIMO_Layers, configuration, scc, NULL); + NR_BWP_Uplink_t *ubwp = config_uplinkBWP(true, uid, maxMIMO_Layers, configuration, scc, NULL); asn1cSeqAdd(&uplinkConfig->uplinkBWP_ToAddModList->list, ubwp); } @@ -3739,75 +3761,22 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, return cellGroupConfig; } -long ue_supported_ul_layers(const NR_UE_NR_Capability_t *uecap) -{ - long ul_max_layers = 1; - if (uecap - && uecap->featureSets - && uecap->featureSets->featureSetsUplinkPerCC - && uecap->featureSets->featureSetsUplinkPerCC->list.count > 0) { - NR_FeatureSetUplinkPerCC_t *ul_feature_setup_per_cc = uecap->featureSets->featureSetsUplinkPerCC->list.array[0]; - if (ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) { - switch (*ul_feature_setup_per_cc->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) { - case NR_MIMO_LayersUL_twoLayers: - ul_max_layers = 2; - break; - case NR_MIMO_LayersUL_fourLayers: - ul_max_layers = 4; - break; - default: - ul_max_layers = 1; - } - } - } - return ul_max_layers; -} - -static long set_ul_max_layers(const nr_mac_config_t *configuration, const NR_UE_NR_Capability_t *uecap) -{ - return min(ue_supported_ul_layers(uecap), configuration->pusch_AntennaPorts); -} - -NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig, - const nr_mac_config_t *configuration, - const NR_UE_NR_Capability_t *uecap, - const NR_ServingCellConfigCommon_t *scc, - int uid, - int old_bwp, - int new_bwp) +NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig, + const nr_mac_config_t *configuration, + const NR_UE_NR_Capability_t *uecap, + const NR_ServingCellConfigCommon_t *scc, + int uid, + int old_bwp, + int new_bwp) { NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig; NR_ServingCellConfig_t *configDedicated = spCellConfig->spCellConfigDedicated; - *configDedicated->firstActiveDownlinkBWP_Id = new_bwp; + *configDedicated->firstActiveDownlinkBWP_Id = new_bwp != 0; // 1 for any BWP != 0 NR_UplinkConfig_t *uplinkConfig = configDedicated->uplinkConfig; - *uplinkConfig->firstActiveUplinkBWP_Id = new_bwp; + *uplinkConfig->firstActiveUplinkBWP_Id = new_bwp != 0; // 1 for any BWP != 0 + nr_mac_config_t local_config = *configuration; long ul_maxMIMO_Layers = set_ul_max_layers(configuration, uecap); - - // release old BWP - struct NR_ServingCellConfig__downlinkBWP_ToAddModList *dl_BWP_list = configDedicated->downlinkBWP_ToAddModList; - struct NR_UplinkConfig__uplinkBWP_ToAddModList *ul_BWP_list = uplinkConfig->uplinkBWP_ToAddModList; - if (old_bwp > 0) { // we need to remove old BWP only if it is not the initial - AssertFatal(dl_BWP_list, "Source BWP %d should be present in the list\n", old_bwp); - AssertFatal(ul_BWP_list, "Source BWP %d should be present in the list\n", old_bwp); - NR_BWP_Id_t id = dl_BWP_list->list.array[0]->bwp_Id; - if (!configDedicated->downlinkBWP_ToReleaseList) - configDedicated->downlinkBWP_ToReleaseList = calloc_or_fail(1, sizeof(*configDedicated->downlinkBWP_ToReleaseList)); - asn1cSequenceAdd(configDedicated->downlinkBWP_ToReleaseList->list, NR_BWP_Id_t, rel_id); - *rel_id = id; - AssertFatal(configDedicated->downlinkBWP_ToReleaseList->list.count == 1, - "logic error: there shouldn't be more than 1 BWP to release, but downlinkBWP_ToReleaseList has %d\n", - configDedicated->downlinkBWP_ToReleaseList->list.count); - - id = ul_BWP_list->list.array[0]->bwp_Id; - if (!uplinkConfig->uplinkBWP_ToReleaseList) - uplinkConfig->uplinkBWP_ToReleaseList = calloc_or_fail(1, sizeof(*uplinkConfig->uplinkBWP_ToReleaseList)); - asn1cSequenceAdd(uplinkConfig->uplinkBWP_ToReleaseList->list, NR_BWP_Id_t, ul_rel_id); - *ul_rel_id = id; - AssertFatal(uplinkConfig->uplinkBWP_ToReleaseList->list.count == 1, - "logic error: there shouldn't be more than 1 BWP to release, but uplinkBWP_ToReleaseList has %d\n", - uplinkConfig->uplinkBWP_ToReleaseList->list.count); - } - + local_config.first_active_bwp = new_bwp; uint64_t bitmap = get_ssb_bitmap(scc); const int pdsch_AntennaPorts = configuration->pdsch_AntennaPorts.N1 * configuration->pdsch_AntennaPorts.N2 * configuration->pdsch_AntennaPorts.XP; @@ -3817,23 +3786,22 @@ NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_ configDedicated->initialDownlinkBWP = calloc_or_fail(1, sizeof(*configDedicated->initialDownlinkBWP)); if (!uplinkConfig->initialUplinkBWP) uplinkConfig->initialUplinkBWP = calloc_or_fail(1, sizeof(*uplinkConfig->initialUplinkBWP)); - uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, ul_maxMIMO_Layers, uid); - configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, configuration); + uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, &local_config, ul_maxMIMO_Layers, uecap, uid); + configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, uecap, &local_config); } else { if (!configDedicated->downlinkBWP_ToAddModList) configDedicated->downlinkBWP_ToAddModList = calloc_or_fail(1, sizeof(*configDedicated->downlinkBWP_ToAddModList)); NR_BWP_Downlink_t *dl_bwp = config_downlinkBWP(scc, uecap, pdsch_AntennaPorts, - configuration->force_256qam_off, - new_bwp - 1, + local_config.force_256qam_off, true, - configuration); + &local_config); asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, dl_bwp); if (!uplinkConfig->uplinkBWP_ToAddModList) uplinkConfig->uplinkBWP_ToAddModList = calloc_or_fail(1, sizeof(*uplinkConfig->uplinkBWP_ToAddModList)); - NR_BWP_Uplink_t *ul_bwp = config_uplinkBWP(new_bwp - 1, true, uid, ul_maxMIMO_Layers, configuration, scc, uecap); + NR_BWP_Uplink_t *ul_bwp = config_uplinkBWP(true, uid, ul_maxMIMO_Layers, &local_config, scc, uecap); asn1cSeqAdd(&uplinkConfig->uplinkBWP_ToAddModList->list, ul_bwp); } @@ -3841,21 +3809,19 @@ NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_ configDedicated->csi_MeasConfig->choice.setup = get_csiMeasConfig(configDedicated, uecap, scc, - configuration, + &local_config, uid, - new_bwp, + *uplinkConfig->firstActiveUplinkBWP_Id, bitmap); // we temporarily need to keep both the old and the new BWP in the CG used by the gNB // while removing the old from the CG sent to the UE - if (old_bwp > 0) { - NR_CellGroupConfig_t *clone_cg = NULL; - const int copy_result = asn_copy(&asn_DEF_NR_CellGroupConfig, (void **)&clone_cg, cellGroupConfig); - AssertFatal(copy_result == 0, "unable to copy NR_CellGroupConfig for cloning\n"); + NR_CellGroupConfig_t *clone_cg = NULL; + const int copy_result = asn_copy(&asn_DEF_NR_CellGroupConfig, (void **)&clone_cg, cellGroupConfig); + AssertFatal(copy_result == 0, "unable to copy NR_CellGroupConfig for cloning\n"); + if (old_bwp > 0) clean_bwp_structures(clone_cg->spCellConfig); - return clone_cg; - } - return NULL; + return clone_cg; } void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, @@ -3875,6 +3841,20 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig = spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup; set_dl_maxmimolayers(pdsch_servingcellconfig, scc, uecap, configuration->maxMIMO_layers); + if (configuration->disable_harq) { + if (!pdsch_servingcellconfig->ext3) + pdsch_servingcellconfig->ext3 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->present = NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_setup; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf = calloc(4, sizeof(uint8_t)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.size = 4; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.bits_unused = 0; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[0] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[1] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[2] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[3] = 0xFF; + } + NR_CSI_MeasConfig_t *csi_MeasConfig = spCellConfigDedicated->csi_MeasConfig->choice.setup; for (int report = 0; report < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; report++) { NR_CSI_ReportConfig_t *csirep = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[report]; @@ -3954,11 +3934,6 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, } } -void free_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig) -{ - ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, cellGroupConfig); -} - int encode_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, uint8_t *buffer, int max_buffer_size) { asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, cellGroupConfig, buffer, max_buffer_size); @@ -3968,14 +3943,6 @@ int encode_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, uint8_t *buffe return (enc_rval.encoded + 7) / 8; } -NR_CellGroupConfig_t *decode_cellGroupConfig(const uint8_t *buffer, int buffer_size) -{ - NR_CellGroupConfig_t *cellGroupConfig = NULL; - asn_dec_rval_t rval = uper_decode(NULL, &asn_DEF_NR_CellGroupConfig, (void **)&cellGroupConfig, buffer, buffer_size, 0, 0); - AssertFatal(rval.code == RC_OK, "could not decode cellGroupConfig\n"); - return cellGroupConfig; -} - static NR_ServingCellConfigCommon_t *clone_ServingCellConfigCommon(const NR_ServingCellConfigCommon_t *scc) { if (scc == NULL) @@ -4054,10 +4021,7 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC ulConfig->initialUplinkBWP = initialUplinkBWP; initialUplinkBWP->pucch_Config = NULL; - initialUplinkBWP->pusch_Config = config_pusch(configuration->use_deltaMCS, - servingcellconfigcommon, - uecap, - configuration->ptrs); + initialUplinkBWP->pusch_Config = config_pusch(configuration, servingcellconfigcommon, uecap); long maxMIMO_Layers = set_ul_max_layers(configuration, uecap); int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, @@ -4072,44 +4036,27 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC configuration->do_SRS); // Downlink BWPs - int n_dl_bwp = 1; int firstActiveDownlinkBWP_Id = 1; - if (configuration->num_additional_bwps > 0) { - n_dl_bwp = configuration->num_additional_bwps; - firstActiveDownlinkBWP_Id = configuration->first_active_bwp; - } configDedicated->downlinkBWP_ToAddModList = calloc(1, sizeof(*configDedicated->downlinkBWP_ToAddModList)); - for (int bwp_loop = 0; bwp_loop < n_dl_bwp; bwp_loop++) { - NR_BWP_Downlink_t *bwp = config_downlinkBWP(servingcellconfigcommon, - uecap, - dl_antenna_ports, - configuration->force_256qam_off, - bwp_loop, - false, - configuration); - asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, bwp); - configDedicated->firstActiveDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->firstActiveDownlinkBWP_Id)); - *configDedicated->firstActiveDownlinkBWP_Id = firstActiveDownlinkBWP_Id; - configDedicated->defaultDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->defaultDownlinkBWP_Id)); - *configDedicated->defaultDownlinkBWP_Id = 1; - } + NR_BWP_Downlink_t *bwp = config_downlinkBWP(servingcellconfigcommon, + uecap, + dl_antenna_ports, + configuration->force_256qam_off, + false, + configuration); + asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, bwp); + configDedicated->firstActiveDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->firstActiveDownlinkBWP_Id)); + *configDedicated->firstActiveDownlinkBWP_Id = firstActiveDownlinkBWP_Id; + configDedicated->defaultDownlinkBWP_Id = calloc(1, sizeof(*configDedicated->defaultDownlinkBWP_Id)); + *configDedicated->defaultDownlinkBWP_Id = 1; // Uplink BWPs - int n_ul_bwp = 1; int firstActiveUplinkBWP_Id = 1; - if (configuration->num_additional_bwps > 0) { - n_ul_bwp = configuration->num_additional_bwps; - firstActiveUplinkBWP_Id = configuration->first_active_bwp; - } - if (n_ul_bwp > 0) { - ulConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*ulConfig->uplinkBWP_ToAddModList)); - for (int bwp_loop = 0; bwp_loop < n_ul_bwp; bwp_loop++) { - NR_BWP_Uplink_t *ubwp = config_uplinkBWP(bwp_loop, false, uid, maxMIMO_Layers, configuration, servingcellconfigcommon, uecap); - asn1cSeqAdd(&ulConfig->uplinkBWP_ToAddModList->list, ubwp); - } - ulConfig->firstActiveUplinkBWP_Id = calloc(1, sizeof(*ulConfig->firstActiveUplinkBWP_Id)); - *ulConfig->firstActiveUplinkBWP_Id = firstActiveUplinkBWP_Id; - } + ulConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*ulConfig->uplinkBWP_ToAddModList)); + NR_BWP_Uplink_t *ubwp = config_uplinkBWP(false, uid, maxMIMO_Layers, configuration, servingcellconfigcommon, uecap); + asn1cSeqAdd(&ulConfig->uplinkBWP_ToAddModList->list, ubwp); + ulConfig->firstActiveUplinkBWP_Id = calloc(1, sizeof(*ulConfig->firstActiveUplinkBWP_Id)); + *ulConfig->firstActiveUplinkBWP_Id = firstActiveUplinkBWP_Id; configDedicated->bwp_InactivityTimer = NULL; configDedicated->downlinkBWP_ToReleaseList = NULL; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h index 270aed4b71..6752db8bc8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h @@ -96,9 +96,7 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, const NR_UE_NR_Capability_t *uecap, const nr_mac_config_t *configuration, const NR_ServingCellConfigCommon_t *scc); -void free_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig); int encode_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, uint8_t *buffer, int max_buffer_size); -NR_CellGroupConfig_t *decode_cellGroupConfig(const uint8_t *buffer, int max_buffer_size); /* Note: this function returns a new CellGroupConfig for a user with given * configuration, but it will also overwrite the ServingCellConfig passed in @@ -124,13 +122,13 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, NR_RLC_Config_PR rlc_conf, long priority, const nr_rlc_configuration_t *default_rlc_config); -NR_CellGroupConfig_t * update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig, - const nr_mac_config_t *configuration, - const NR_UE_NR_Capability_t *uecap, - const NR_ServingCellConfigCommon_t *scc, - int uid, - int old_bwp, - int new_bwp); +NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t *cellGroupConfig, + const nr_mac_config_t *configuration, + const NR_UE_NR_Capability_t *uecap, + const NR_ServingCellConfigCommon_t *scc, + int uid, + int old_bwp, + int new_bwp); NR_MeasurementTimingConfiguration_t *get_nr_mtc(uint8_t *buf, uint32_t len); measgap_config_t create_measgap_config(const NR_MeasurementTimingConfiguration_t *mtc, int scs, int min_rxtxtime); int encode_measgap_config(const measgap_config_t *c, uint8_t *buf); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 0939b52c7a..09f3218f1e 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -123,7 +123,7 @@ static int handle_bcch_bch(NR_UE_MAC_INST_t *mac, else mac->frequency_range = FR1; // fixed 3 bytes MIB PDU - nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, cell_id, ssb_arfcn, NR_BCCH_BCH, (uint8_t *) pduP, 3); + nr_mac_rrc_data_ind_ue(mac->ue_id, cc_id, gNB_index, 0, 0, 0, 0, cell_id, ssb_arfcn, NR_BCCH_BCH, (uint8_t *) pduP, 3); return 0; } @@ -134,10 +134,11 @@ static int handle_bcch_dlsch(NR_UE_MAC_INST_t *mac, uint8_t ack_nack, uint8_t *pduP, uint32_t pdu_len, + int hfn, int frame, int slot) { - nr_ue_decode_BCCH_DL_SCH(mac, cc_id, gNB_index, ack_nack, pduP, pdu_len, frame, slot); + nr_ue_decode_BCCH_DL_SCH(mac, cc_id, gNB_index, ack_nack, pduP, pdu_len, hfn, frame, slot); return 0; } @@ -301,6 +302,7 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio rx_indication_body.pdsch_pdu.ack_nack, rx_indication_body.pdsch_pdu.pdu, rx_indication_body.pdsch_pdu.pdu_length, + dl_info->hfn, dl_info->frame, dl_info->slot)) << FAPI_NR_RX_PDU_TYPE_SIB; break; @@ -389,6 +391,7 @@ static void handle_sl_bch(int ue_id, sl_nr_ue_mac_params_t *sl_mac, uint8_t *const sl_mib, const uint8_t len, + int hfn_rx, uint16_t frame_rx, uint16_t slot_rx, uint16_t rx_slss_id) @@ -421,7 +424,7 @@ static void handle_sl_bch(int ue_id, sl_mac->decoded_DFN = frame; sl_mac->decoded_slot = slot; - nr_mac_rrc_data_ind_ue(ue_id, 0, 0, frame_rx, slot_rx, 0, rx_slss_id, 0, NR_SBCCH_SL_BCH, (uint8_t *)sl_mib, len); + nr_mac_rrc_data_ind_ue(ue_id, 0, 0, hfn_rx, frame_rx, slot_rx, 0, rx_slss_id, 0, NR_SBCCH_SL_BCH, (uint8_t *)sl_mib, len); return; } @@ -433,6 +436,7 @@ if PSBCH rx - handle_psbch() if PSSCH DATa rx - handle slsch() */ void sl_nr_process_rx_ind(int ue_id, + int hfn, uint32_t frame, uint32_t slot, sl_nr_ue_mac_params_t *sl_mac, @@ -456,6 +460,7 @@ void sl_nr_process_rx_ind(int ue_id, sl_mac, rx_ind->rx_indication_body[num_pdus - 1].ssb_pdu.psbch_payload, 4, + hfn, frame, slot, rx_ind->rx_indication_body[num_pdus - 1].ssb_pdu.rx_slss_id); @@ -488,11 +493,12 @@ void nr_ue_sl_indication(nr_sidelink_indication_t *sl_indication) uint16_t slot = sl_indication->slot_rx; uint16_t frame = sl_indication->frame_rx; + int hfn = sl_indication->hfn_rx; sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS; if (sl_indication->rx_ind) { - sl_nr_process_rx_ind(ue_id, frame, slot, sl_mac, sl_indication->rx_ind); + sl_nr_process_rx_ind(ue_id, hfn, frame, slot, sl_mac, sl_indication->rx_ind); } else { nr_ue_sidelink_scheduler(sl_indication, mac); } diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index a1175282f0..66afa266f8 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -56,6 +56,8 @@ typedef struct { uint32_t gNB_index; /// component carrier id int cc_id; + /// hyper frame number + int hfn; /// frame frame_t frame; /// slot @@ -101,10 +103,14 @@ typedef struct { uint32_t gNB_index; /// component carrier id int cc_id; + /// hyper frame number rx + int hfn_rx; /// frame rx frame_t frame_rx; /// slot rx uint32_t slot_rx; + /// hyper frame number tx + int hfn_tx; /// frame tx frame_t frame_tx; /// slot tx diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index e1d2dbe841..d2f08fd4b4 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1092,7 +1092,13 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context const f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; uint32_t ssb_arfcn = get_ssb_arfcn(du); LOG_I(NR_RRC, "Reestablishment update key pci=%d, earfcn_dl=%u\n", cell_info->nr_pci, ssb_arfcn); - nr_derive_key_ng_ran_star(cell_info->nr_pci, ssb_arfcn, ue_p->nh_ncc > 0 ? ue_p->nh : ue_p->kgnb, ue_p->kgnb); + + /* Per TS 33.501 6.9.2.3.4: When sending RRCReestablishment with nextHopChainingCount, + * we're staying at the same NCC level (not advancing), so use horizontal derivation + * from the currently active KgNB. Vertical derivation (from NH) is only used when + * advancing to a new NCC level, which happens during handover or masterKeyUpdate. */ + const uint8_t *base_key = ue_p->kgnb; + nr_derive_key_ng_ran_star(cell_info->nr_pci, ssb_arfcn, base_key, ue_p->kgnb); int size = do_RRCReestablishment(ue_context_pP->ue_context.nh_ncc, buffer, NR_RRC_BUF_SIZE, xid); LOG_A(NR_RRC, "Send RRCReestablishment [%d bytes] to RNTI %04x\n", size, ue_p->rnti); @@ -2434,10 +2440,8 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p, sctp_as gNB_RRC_INST *rrc = RC.nrrrc[instance]; rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_CU_ue_id); int srbid = 1; - // valid AMF UE NGAP ID range is 0..2^40-1 - if (!ue_context_p || ue_context_p->ue_context.amf_ue_ngap_id >= (1LL << 40)) { - const char *reason = !ue_context_p ? "could not find UE context" : "no AMF"; - LOG_W(RRC, "%s for CU UE ID %u: auto-generate release command\n", reason, req->gNB_CU_ue_id); + if (!ue_context_p) { + LOG_W(RRC, "could not find UE context for CU UE ID %u: auto-generate release command\n", req->gNB_CU_ue_id); uint8_t buffer[NR_RRC_BUF_SIZE] = {0}; int size = do_NR_RRCRelease(buffer, NR_RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(0)); RETURN_IF_INVALID_ASSOC_ID(assoc_id); @@ -2579,17 +2583,9 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i // nothing is to be done, we wait for confirmation to release the UE in the // CU/DU) if (UE->ho_context && UE->ho_context->target && UE->ho_context->source) { - nr_ho_target_cu_t *target_ctx = UE->ho_context->target; - f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); - ue_data.secondary_ue = target_ctx->du_ue_id; - ue_data.du_assoc_id = target_ctx->du->assoc_id; - bool success = cu_update_f1_ue_data(UE->rrc_ue_id, &ue_data); - DevAssert(success); - LOG_I(NR_RRC, "UE %d handover: update RNTI from %04x to %04x\n", UE->rrc_ue_id, UE->rnti, target_ctx->new_rnti); nr_ho_source_cu_t *source_ctx = UE->ho_context->source; DevAssert(source_ctx->old_rnti == UE->rnti); - UE->rnti = target_ctx->new_rnti; - UE->nr_cellid = target_ctx->du->setup_req->cell[0].info.nr_cellid; + nr_rrc_apply_target_context(UE); } } @@ -3182,10 +3178,6 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_dc_overall_timeout(instance, &X2AP_ENDC_DC_OVERALL_TIMEOUT(msg_p)); break; - case NGAP_UE_CONTEXT_RELEASE_REQ: - rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(msg_p, instance); - break; - case NGAP_UE_CONTEXT_RELEASE_COMMAND: rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p, instance); break; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 979fe0ac5e..19bab47b67 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -717,6 +717,7 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE->amf_ue_ngap_id = req->amf_ue_ngap_id; UE->nas_pdu = req->nas_pdu; rrc_forward_ue_nas_message(rrc, UE); return 0; @@ -1049,7 +1050,8 @@ int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE return 0; } -//------------------------------------------------------------------------------ +/** @brief Send UE Context Release Request (NG-RAN node initiated) + * Direction: NG-RAN node -> AMF (8.3.2.2 3GPP TS 38.413) */ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, const rrc_gNB_ue_context_t *const ue_context_pP, const ngap_cause_t causeP) @@ -1068,40 +1070,12 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, // PDU Session Resource List (optional) FOR_EACH_SEQ_ARR(rrc_pdu_session_param_t *, session, &UE->pduSessions) { DevAssert(req->nb_of_pdusessions < NGAP_MAX_PDU_SESSION); - req->pdusessions[req->nb_of_pdusessions].pdusession_id = session->param.pdusession_id; + req->pdusession_ids[req->nb_of_pdusessions] = session->param.pdusession_id; req->nb_of_pdusessions++; } itti_send_msg_to_task(TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_mod_idP), msg); } } -/*------------------------------------------------------------------------------*/ -int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t instance) -{ - uint32_t gNB_ue_ngap_id; - gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_REQ(msg_p).gNB_ue_ngap_id; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id); - - if (ue_context_p == NULL) { - /* Can not associate this message to an UE index, send a failure to ngAP and discard it! */ - MessageDef *msg_fail_p; - LOG_W(RRC, "[gNB %ld] In NGAP_UE_CONTEXT_RELEASE_REQ: unknown UE from gNB_ue_ngap_id (%u)\n", - instance, - gNB_ue_ngap_id); - msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP); /* TODO change message ID. */ - NGAP_UE_CONTEXT_RELEASE_RESP(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); - return (-1); - } else { - - /* Send the response */ - MessageDef *msg_resp_p; - msg_resp_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP); - NGAP_UE_CONTEXT_RELEASE_RESP(msg_resp_p).gNB_ue_ngap_id = gNB_ue_ngap_id; - itti_send_msg_to_task(TASK_NGAP, instance, msg_resp_p); - return (0); - } -} /** @brief Sends the NG Handover Failure from the Target NG-RAN to the AMF */ void rrc_gNB_send_NGAP_HANDOVER_FAILURE(gNB_RRC_INST *rrc, ngap_handover_failure_t *msg) @@ -1557,9 +1531,9 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(ngap_pdusession_release_comm cmd->nb_pdusessions_torelease); e1ap_bearer_mod_req_t req = {0}; for (int pdusession = 0; pdusession < cmd->nb_pdusessions_torelease; pdusession++) { - rrc_pdu_session_param_t *pduSession = find_pduSession(&UE->pduSessions, cmd->pdusession_release_params[pdusession].pdusession_id); + rrc_pdu_session_param_t *pduSession = find_pduSession(&UE->pduSessions, cmd->pdusession_ids[pdusession]); if (!pduSession) { - LOG_E(NR_RRC, "Failed to release non-existing PDU Session %d\n", cmd->pdusession_release_params[pdusession].pdusession_id); + LOG_E(NR_RRC, "Failed to release non-existing PDU Session %d\n", cmd->pdusession_ids[pdusession]); continue; } if (pduSession->status == PDU_SESSION_STATUS_TORELEASE) { @@ -1676,7 +1650,7 @@ void rrc_gNB_send_NGAP_HANDOVER_REQUIRED(gNB_RRC_INST *rrc, msg.source2target->ue_history_info.cause->type = NGAP_CAUSE_RADIO_NETWORK; msg.source2target->ue_history_info.cause->value = NGAP_CAUSE_RADIO_NETWORK_HANDOVER_DESIRABLE_FOR_RADIO_REASON; msg.source2target->ue_history_info.type = NGAP_CellSize_small; - msg.source2target->ue_history_info.time_in_cell = 500; // dummy number for now + msg.source2target->ue_history_info.time_in_cell = min(time(NULL) - UE->last_seen, 4095); msg.source2target->ue_history_info.id = target_cell; /* Fill both PDU Session Resource List IE (M) in Handover Required diff --git a/openair2/RRC/NR/rrc_gNB_mobility.c b/openair2/RRC/NR/rrc_gNB_mobility.c index e570682ce8..1fc274db5b 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.c +++ b/openair2/RRC/NR/rrc_gNB_mobility.c @@ -63,6 +63,34 @@ static void free_ho_ctx(nr_handover_context_t *ho_ctx) free(ho_ctx); } +/** @brief Apply target handover context: update F1AP associations and RNTI */ +void nr_rrc_apply_target_context(gNB_RRC_UE_t *UE) +{ + DevAssert(UE->ho_context); + DevAssert(UE->ho_context->target); + nr_ho_target_cu_t *target_ctx = UE->ho_context->target; + f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); + LOG_I(NR_RRC, + "UE %d: update CU F1AP Context DU UE ID %u => %u and RNTI %04x => %04x\n", + UE->rrc_ue_id, + ue_data.secondary_ue, + target_ctx->du_ue_id, + UE->rnti, + target_ctx->new_rnti); + + /* update F1 data: secondary UE association and DU association */ + ue_data.secondary_ue = target_ctx->du_ue_id; + ue_data.du_assoc_id = target_ctx->du->assoc_id; + bool success = cu_update_f1_ue_data(UE->rrc_ue_id, &ue_data); + DevAssert(success); + + /* update UE RNTI */ + UE->rnti = target_ctx->new_rnti; + + /* update UE NR cell ID */ + UE->nr_cellid = target_ctx->du->setup_req->cell[0].info.nr_cellid; +} + /** @brief Fill DRB to Be Setup List in F1 UE Context Setup Request (optional list) * @return 0 if list is empty, list size otherwise */ static int fill_drb_to_be_setup(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, f1ap_drb_to_setup_t drbs[MAX_DRBS_PER_UE]) @@ -464,10 +492,7 @@ static void nr_rrc_n2_ho_acknowledge(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE) /* this is the callback for N2 handover after F1 UE context setup response in * the handover case. Check that there was no associated DU, then set it */ AssertFatal(previous_data.secondary_ue == -1, "there was already a DU present\n"); - previous_data.secondary_ue = UE->ho_context->target->du_ue_id; - bool success = cu_update_f1_ue_data(UE->rrc_ue_id, &previous_data); - DevAssert(success); - LOG_I(NR_RRC, "Updated CU F1AP Context for UE %d, DU Id : %u\n", UE->rrc_ue_id, UE->ho_context->target->du_ue_id); + nr_rrc_apply_target_context(UE); byte_array_t hoCommand = rrc_gNB_encode_HandoverCommand(UE, rrc); if (hoCommand.len < 0) { diff --git a/openair2/RRC/NR/rrc_gNB_mobility.h b/openair2/RRC/NR/rrc_gNB_mobility.h index 88e3548220..54691c2edd 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.h +++ b/openair2/RRC/NR/rrc_gNB_mobility.h @@ -110,4 +110,6 @@ void nr_rrc_trigger_n2_ho_target(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue); byte_array_t *get_meas_timing_config(const NR_MeasurementTimingConfiguration_t *mtc, const NR_MeasConfig_t *measConfig); +void nr_rrc_apply_target_context(gNB_RRC_UE_t *UE); + #endif /* RRC_GNB_MOBILITY_H_ */ diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index bae8915916..a1af257282 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -59,6 +59,7 @@ void nr_mac_rrc_sync_ind(const module_id_t module_id, const frame_t frame, const void nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, + const int hfn, const frame_t frame, const int slot, const rnti_t rnti, @@ -97,6 +98,7 @@ void nr_mac_rrc_data_ind_ue(const module_id_t module_id, else { NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = 0; } + NR_RRC_MAC_BCCH_DATA_IND (message_p).hfn = hfn; NR_RRC_MAC_BCCH_DATA_IND (message_p).frame = frame; //frameP NR_RRC_MAC_BCCH_DATA_IND (message_p).slot = slot; NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index; @@ -120,6 +122,7 @@ void nr_mac_rrc_data_ind_ue(const module_id_t module_id, message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_SBCCH_DATA_IND); memset(NR_RRC_MAC_SBCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); memcpy(NR_RRC_MAC_SBCCH_DATA_IND (message_p).sdu, pduP, sdu_size); + NR_RRC_MAC_SBCCH_DATA_IND (message_p).hfn = hfn; NR_RRC_MAC_SBCCH_DATA_IND (message_p).frame = frame; //frameP NR_RRC_MAC_SBCCH_DATA_IND (message_p).slot = slot; NR_RRC_MAC_SBCCH_DATA_IND (message_p).sdu_size = sdu_size; @@ -139,14 +142,18 @@ void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id) nr_rrc_mac_config_req_reset(instance_id, msg->payload.config_reset.cause); break; case NR_MAC_RRC_CONFIG_CG: - nr_rrc_mac_config_req_cg(instance_id, 0, msg->payload.config_cg.cellGroupConfig, msg->payload.config_cg.UE_NR_Capability); + nr_rrc_mac_config_req_cg(instance_id, + 0, + msg->payload.config_cg.hfn, + msg->payload.config_cg.frame, + msg->payload.config_cg.cellGroupConfig, + msg->payload.config_cg.UE_NR_Capability); ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, msg->payload.config_cg.cellGroupConfig); break; case NR_MAC_RRC_CONFIG_MIB: nr_rrc_mac_config_req_mib(instance_id, 0, msg->payload.config_mib.bcch->message.choice.mib, - msg->payload.config_mib.get_sib, msg->payload.config_mib.access_barred); ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, msg->payload.config_mib.bcch); break; @@ -157,9 +164,15 @@ void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id) SEQUENCE_free(&asn_DEF_NR_SIB1, msg->payload.config_sib1.sib1, ASFM_FREE_EVERYTHING); } break; case NR_MAC_RRC_CONFIG_OTHER_SIB: { - bool can_start_ra = msg->payload.config_other_sib.can_start_ra; - nr_rrc_mac_config_other_sib(instance_id, msg->payload.config_other_sib.sib19, can_start_ra); + nr_rrc_mac_config_other_sib(instance_id, + msg->payload.config_other_sib.sib19, + msg->payload.config_other_sib.hfn, + msg->payload.config_other_sib.frame, + msg->payload.config_other_sib.can_start_ra); } break; + case NR_MAC_RRC_SCHED_SIB: + nr_rrc_mac_sched_sib(instance_id, msg->payload.sched_sib.get_sib); + break; case NR_MAC_RRC_RESUME_RB: nr_rrc_mac_resume_rb(instance_id, msg->payload.resume_rb.is_srb, msg->payload.resume_rb.rb_id); break; @@ -183,10 +196,11 @@ void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti, bool prepare_ itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(mod_id), message_p); } -void nr_ue_rrc_timer_trigger(int instance, int frame, int gnb_id) +void nr_ue_rrc_timer_trigger(int instance, int hfn, int frame, int gnb_id) { MessageDef *message_p; message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NRRRC_FRAME_PROCESS); + NRRRC_FRAME_PROCESS(message_p).hfn = hfn; NRRRC_FRAME_PROCESS(message_p).frame = frame; NRRRC_FRAME_PROCESS(message_p).gnb_id = gnb_id; LOG_D(NR_RRC, "RRC timer trigger: frame %d\n", frame); diff --git a/openair2/RRC/NR_UE/L2_interface_ue.h b/openair2/RRC/NR_UE/L2_interface_ue.h index 5c7a4c16af..9a5e5ee2a8 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.h +++ b/openair2/RRC/NR_UE/L2_interface_ue.h @@ -29,6 +29,7 @@ void nr_mac_rrc_sync_ind(const module_id_t module_id, const frame_t frame, const void nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, + const int hfn, const frame_t frame, const int slot, const rnti_t rnti, @@ -45,7 +46,7 @@ void nr_mac_rrc_meas_ind_ue(module_id_t module_id, int rsrp_dBm); void nr_mac_rrc_inactivity_timer_ind(const module_id_t mod_id); void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti, bool prepare_payload); -void nr_ue_rrc_timer_trigger(int instance, int frame, int gnb_id); +void nr_ue_rrc_timer_trigger(int instance, int hfn, int frame, int gnb_id); void nr_mac_rrc_ra_ind(const module_id_t mod_id, bool success); void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id); #endif diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 27e1dc0bb1..10c38c1ceb 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -248,19 +248,19 @@ static int eval_epoch_time(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntnc static int get_ntn_timervalues(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntncfg, int diff_frames, int *val430_ms) { int val430 = get_ulsyncvalidityduration_timer_value(ntncfg); - int sib19_periodicity_ms = (SI_info->sib19_periodicity + 1) * 10; + int sib19_periodicity_ms = SI_info->sib19_periodicity * 10; *val430_ms = val430 * 1000 + diff_frames * 10; // in ms if (*val430_ms <= sib19_periodicity_ms) LOG_E(NR_RRC, "Too small T430 value. Might result in frequent ULSYNC failure\n"); - // Depending on ulsyncvalidity duration, SIB19 timer expires 15secs/2secs before T430 - // LArger values might be used for GEO and epoch time interval can be around 10 secs - // Lower values will be used for NGSO (LEO/MEO), epoch time interval can be between 2-3 secs. - // TODO remove the hardoded values and define a better strategy to determine the time of expiry - // with real GEO/LEO/MEO SATs. - int expire_before_ms = ((val430 >= 120) ? 10000 : 2000); - int diff = *val430_ms - expire_before_ms; - int sib19_timer_ms = (diff > 0) ? diff : ((*val430_ms - sib19_periodicity_ms) > 0) ? (*val430_ms - sib19_periodicity_ms) : 0; + // by default SIB19 reception is started from the middle of the ulsyncvalidity duration.(i.e val430 in ms / 2) + int sib19_timer_ms = val430 * 500 + diff_frames * 10; + + // if this is less than the SIB19 periodicity, use that instead. + // set the timer to expire 1 frame (10 ms) before periodicity, to not miss the SIB19 + if (sib19_timer_ms <= sib19_periodicity_ms) + sib19_timer_ms = sib19_periodicity_ms - 10; + LOG_I(NR_RRC, "val430:%d s, T430:%d ms, sib19_timer:%d ms\n", val430, *val430_ms, sib19_timer_ms); return sib19_timer_ms; } @@ -292,7 +292,7 @@ static void nr_rrc_process_ntnconfig(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *S nr_timer_start(&SI_info->SInfo_r17.sib19_timer); } -static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, NR_UE_RRC_INST_t *rrc, int frame) +static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, NR_UE_RRC_INST_t *rrc, int hfn, int frame) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN); @@ -381,6 +381,8 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, rrc_msg.payload_type = NR_MAC_RRC_CONFIG_OTHER_SIB; nr_mac_rrc_config_other_sib_t *sib19_msg = &rrc_msg.payload.config_other_sib; asn_copy(&asn_DEF_NR_SIB19_r17, (void **)&sib19_msg->sib19, sib19); + sib19_msg->hfn = hfn; + sib19_msg->frame = frame; sib19_msg->can_start_ra = rrc->is_NTN_UE; nr_rrc_send_msg_to_mac(rrc, &rrc_msg); } @@ -525,13 +527,141 @@ static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_inf nr_rrc_send_msg_to_mac(rrc, &rrc_msg); } -static void nr_rrc_nh_update(NR_UE_RRC_INST_t *rrc, uint8_t *kamf, uint8_t *sync_input) +/** @brief Synchronize NH chain based on nextHopChainingCount + * + * This function synchronizes the NH parameter chain as specified in 3GPP TS 33.501 Annex A.10. + * Use cases: Master Key Update, RRC Reestablishment: The UE receives an NCC value that is + * different from the NCC associated with the currently active KgNB. The NH chain is synchronized + * by computing the function defined in Annex A.10 iteratively (and increasing the NCC value until + * it matches the NCC value received from the source ng-gNB). + * + * @param kamf K_AMF key from NAS + * @param kgnb Current KgNB key (input/output) + * @param nh Current NH parameter (input/output) + * @param nhcc Pointer to current nextHopChainingCount (input/output) + * @param target_ncc Target nextHopChainingCount value to synchronize to */ +static void nr_sync_nh_chain(const uint8_t kamf[SECURITY_KEY_LEN], + uint8_t kgnb[SECURITY_KEY_LEN], + uint8_t nh[SECURITY_KEY_LEN], + uint64_t *nhcc, + const int8_t target_ncc) { - uint8_t nh[SECURITY_KEY_LEN] = {0}; - nr_derive_nh(kamf, sync_input, nh); - log_hex_buffer("Sync input = stored NH", rrc->nh, SECURITY_KEY_LEN); - memcpy(rrc->nh, nh, SECURITY_KEY_LEN); - rrc->nhcc++; // Increase stored nextHopChainingCount + // If the UE received an NCC value that was different from the NCC associated with the + // currently active KgNB, the UE shall first synchronize the locally kept NH + // parameter by computing the function defined in Annex A.10 iteratively (and increasing + // the NCC value until it matches the NCC value received from the source ng-gNB). + if (target_ncc <= *nhcc) { + LOG_W(NR_RRC, "Received NCC=%d is less than or equal to current nhcc=%ld (nothing to sync)\n", target_ncc, *nhcc); + return; + } + if (target_ncc > *nhcc) { + LOG_I(NR_RRC, "Synchronizing NH chain: current nhcc=%ld, target ncc=%d\n", *nhcc, target_ncc); + if (*nhcc == 0) { + // First derivation: derive KgNB from KAMF, then derive NH from KgNB (per TS 33.501 A.10) + // Note: For the first NH derivation, we use UL NAS COUNT = 0 to match the AMF's derivation + // during handover. The AMF derives the first NH using the UL NAS COUNT from the last + // successful NAS SMC, which is 0 for the initial derivation. + derive_kgnb(kamf, 0, kgnb); + nr_derive_nh(kamf, kgnb, nh); + *nhcc = 1; + } + // Following derivations: iterate from current nhcc to target_ncc + for (uint8_t i = *nhcc; i < target_ncc; i++) { + LOG_D(NR_RRC, "Derive keys for ChainingCount = %d\n", i); + nr_derive_nh(kamf, nh, nh); + } + *nhcc = target_ncc; + } +} + +/** @brief Derive KNG-RAN* (KgNB*) using horizontal derivation + * + * This function derives KNG-RAN* from the currently active KgNB (horizontal derivation) + * as specified in 3GPP TS 33.501 Annex A.11 and A.12. + * Used when NCC values match (no NH synchronization needed). + * + * @param pci Physical Cell ID + * @param nr_arfcn_dl NR ARFCN-DL + * @param kgnb Current KgNB key (input/output) + */ +static void nr_derive_kgnb_horizontal(const uint16_t pci, const uint64_t nr_arfcn_dl, uint8_t kgnb[SECURITY_KEY_LEN]) +{ + // When the NCC values match, the UE shall derive the KNG-RAN* from the currently active + // KgNB and the target PCI and its frequency ARFCN-DL using the function defined in Annex A.11 and A.12. + LOG_D(NR_RRC, "Deriving KNG-RAN* using horizontal derivation (from current KgNB)\n"); + nr_derive_key_ng_ran_star(pci, nr_arfcn_dl, kgnb, kgnb); +} + +/** @brief Derive KNG-RAN* (KgNB*) using vertical derivation + * + * This function derives KNG-RAN* from the synchronized NH parameter (vertical derivation) + * as specified in 3GPP TS 33.501 Annex A.11 and A.12. + * Used after NH chain synchronization when NCC values differ. + * + * @param pci Physical Cell ID + * @param nr_arfcn_dl NR ARFCN-DL + * @param kgnb Current KgNB key (input/output) + * @param nh Synchronized NH parameter (input) + */ +static void nr_derive_kgnb_vertical(const uint16_t pci, + const uint64_t nr_arfcn_dl, + uint8_t kgnb[SECURITY_KEY_LEN], + const uint8_t nh[SECURITY_KEY_LEN]) +{ + // When the NCC values match (after synchronization), the UE shall compute the K NG-RAN * + // from the synchronized NH parameter and the target PCI and its frequency ARFCN-DL + // using the function defined in Annex A.11 and A.12. + LOG_D(NR_RRC, "Deriving KNG-RAN* using vertical derivation (from synchronized NH)\n"); + nr_derive_key_ng_ran_star(pci, nr_arfcn_dl, nh, kgnb); +} + +/** @brief Update KgNB based on received nextHopChainingCount + * + * This function implements the common logic for updating KgNB based on received NCC value, + * as specified in 3GPP TS 33.501 6.9.2.3.4. + * + * Per 33.501 6.9.2.3.4 and Fig 6.9.2.1.1-1: + * - If NCC received == current NCC: use horizontal derivation (from currently active KgNB) + * This applies regardless of whether NCC is 0 or >0. For a fixed NCC level, multiple + * horizontal derivations can be done within that level. + * - If NCC received > current NCC: synchronize NH chain (Annex A.10), then use vertical + * derivation (from NH) to enter the new NCC level. + * + * Horizontal derivation = derive KNG-RAN* from currently active KgNB + (PCI, ARFCN-DL) + * Vertical derivation = derive KNG-RAN* from NH + (PCI, ARFCN-DL) + * + * @param rrc RRC instance pointer + * @param kamf K_AMF key from NAS + * @param received_ncc Received nextHopChainingCount value */ +static void nr_update_kgnb_from_ncc(NR_UE_RRC_INST_t *rrc, const uint8_t kamf[SECURITY_KEY_LEN], int8_t received_ncc) +{ + const uint64_t original_nhcc = rrc->nhcc; + + if (received_ncc == original_nhcc) { + // NCC values match: use horizontal derivation from currently active KgNB + // Per TS 33.501 6.9.2.3.4: "derive the KNG-RAN* from the currently active KgNB" + // This applies regardless of NCC being 0 or >0. For a fixed NCC level, we stay + // within that level using horizontal derivations. + LOG_D(NR_RRC, "NCC values match (%d), using horizontal derivation\n", received_ncc); + nr_derive_kgnb_horizontal(rrc->phyCellID, rrc->arfcn_ssb, rrc->kgnb); + } else if (received_ncc < original_nhcc) { + // Note: According to spec, NCC should only increase. If received_ncc < original_nhcc, + // this is an error condition, but we handle it gracefully. + LOG_W(NR_RRC, + "Received NCC=%d is less than current nhcc=%ld (unexpected per spec, NH chain should only increase)\n", + received_ncc, + original_nhcc); + } else { + // received_ncc > original_nhcc: synchronize NH chain first (per 33.501 A.10) + nr_sync_nh_chain(kamf, rrc->kgnb, rrc->nh, &rrc->nhcc, received_ncc); + // Store the received nextHopChainingCount value (per 38.331 5.3.7.5) + LOG_D(NR_RRC, "Synchronizing NH chain to target NCC %d\n", received_ncc); + rrc->nhcc = received_ncc; + // After synchronization, derive KNG-RAN* from synchronized NH (vertical derivation) + // per 33.501 6.9.2.3.4: "When the NCC values match, the UE shall compute the K NG-RAN * + // from the synchronized NH parameter" + nr_derive_kgnb_vertical(rrc->phyCellID, rrc->arfcn_ssb, rrc->kgnb, rrc->nh); + } } /** @brief AS security key update procedure (5.3.5.7 3GPP TS 38.331) */ @@ -543,40 +673,17 @@ void as_security_key_update(NR_UE_RRC_INST_t *rrc, NR_MasterKeyUpdate_t *mku) if (mku->keySetChangeIndicator) { LOG_E(NR_RRC, "derive or update the K gNB key based on the K AMF key, as specified in TS 33.501: not implemented yet\n"); } else { - /* derive or update the K gNB key based on the current K gNB key or the NH, using the nextHopChainingCount - value indicated in the received masterKeyUpdate, as specified in 6.9.2.3.3 3GPP TS 33.501 */ - if (mku->nextHopChainingCount != rrc->nhcc) { - // - If the UE received an NCC value that was different from the NCC associated with the currently active - // K gNB/K eNB, the UE shall first synchronize the locally kept NH parameter by computing the function defined in - // Annex A.10 iteratively (and increasing the NCC value until it matches the NCC value received from the source - // ng-eNB/gNB via the HO command message. - LOG_A(NR_RRC, "Received masterKeyUpdate (nextHopChainingCount %ld): update security keys\n", mku->nextHopChainingCount); - /** @todo: The KAMF should be obtained from NAS. This exchange over ITTI must be synchronized - * with the rest of the RRCReconfiguration procedure, in particular, the RadioBearerConfig - * processing that triggers bearer modifications. Security configueration of bearers must - * complete using the newly derived keys. As a workaround NAS is directly accessed here. */ - nr_ue_nas_t *nas = get_ue_nas_info(rrc->ue_id); - uint8_t *kamf = nas->security.kamf; - log_hex_buffer("Stored kamf", kamf, SECURITY_KEY_LEN); - if (rrc->nhcc == 0) { // First derivation - derive_kgnb(kamf, 0, rrc->kgnb); - log_hex_buffer("Sync input = derived kgnb", rrc->kgnb, SECURITY_KEY_LEN); - nr_rrc_nh_update(rrc, kamf, rrc->kgnb); - } - for (int i = rrc->nhcc; i < mku->nextHopChainingCount; i++) { // Following derivations - LOG_D(NR_RRC, "Derive keys for ChainingCount = %d\n", i); - nr_rrc_nh_update(rrc, kamf, rrc->nh); - } - nr_derive_key_ng_ran_star(rrc->phyCellID, rrc->arfcn_ssb, rrc->nh, rrc->kgnb); - // When the NCC values match, the UE shall compute the K NG-RAN * - // from the synchronized NH parameter and the target PCI and its frequency ARFCN-DL/EARFCN-DL using the - // function defined in Annex A.11 and A.12. - // The UE shall use the KNG-RAN * as the K gNB when communicating with the target gNB and as the KeNB when - // communicating with the target ng-eNB. - } else { - nr_derive_key_ng_ran_star(rrc->phyCellID, rrc->arfcn_ssb, rrc->kgnb, rrc->kgnb); - } - log_hex_buffer("Derived kgnb", rrc->kgnb, SECURITY_KEY_LEN); + LOG_I(NR_RRC, "Received masterKeyUpdate (nextHopChainingCount %ld): update security keys\n", mku->nextHopChainingCount); + /** @todo: The KAMF should be obtained from NAS. This exchange over ITTI must be synchronized + * with the rest of the RRCReconfiguration procedure, in particular, the RadioBearerConfig + * processing that triggers bearer modifications. Security configueration of bearers must + * complete using the newly derived keys. As a workaround NAS is directly accessed here. */ + nr_ue_nas_t *nas = get_ue_nas_info(rrc->ue_id); + const uint8_t *kamf = nas->security.kamf; + // KgNB update (TS 33.501 §6.9.2.3.3): + // If received NCC != local NCC, iteratively derive NH (Annex A.10) until NCC matches. + // Then derive the new KgNB from the synchronized NH. + nr_update_kgnb_from_ncc(rrc, kamf, mku->nextHopChainingCount); } } @@ -748,6 +855,191 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, NR_Rad LOG_I(NR_RRC, "State = NR_RRC_CONNECTED\n"); } +static void nr_rrc_signal_maxrtxindication(int ue_id) +{ + MessageDef *msg = itti_alloc_new_message(TASK_RLC_UE, ue_id, NR_RRC_RLC_MAXRTX); + NR_RRC_RLC_MAXRTX(msg).ue_id = ue_id; + itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, msg); +} + +/** @brief Release all active RLC entities for a UE and set to inactive. + * This is typically used when tearing down all DRBs at UE side, + * such as after a PDU session release or full reconfiguration. + * @param rrc Pointer to NR_UE_RRC_INST_t structure + * @param id Logical Channel ID (must be in range [0, NR_MAX_NUM_LCID-1]) */ +static void nr_rrc_release_rlc_entity(NR_UE_RRC_INST_t *rrc, int id) +{ + DevAssert(rrc); + DevAssert(id >= 0 && id < NR_MAX_NUM_LCID); + if (rrc->active_RLC_entity[id]) { + rrc->active_RLC_entity[id] = false; + nr_rlc_release_entity(rrc->ue_id, id); + LOG_I(RLC, "Released RLC entity: ue_id=%ld, lc_id=%d\n", rrc->ue_id, id); + } +} + +static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, const NR_CellGroupConfig_t *cellGroupConfig) +{ + if (cellGroupConfig->rlc_BearerToReleaseList != NULL) { + for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) { + NR_LogicalChannelIdentity_t *lcid = cellGroupConfig->rlc_BearerToReleaseList->list.array[i]; + AssertFatal(lcid, "LogicalChannelIdentity shouldn't be null here\n"); + nr_rrc_release_rlc_entity(rrc, *lcid); + } + } + + if (cellGroupConfig->rlc_BearerToAddModList != NULL) { + for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) { + NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i]; + NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity; + if (rrc->active_RLC_entity[lcid]) { + if (rlc_bearer->reestablishRLC) + nr_rlc_reestablish_entity(rrc->ue_id, lcid); + if (rlc_bearer->rlc_Config) + nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config); + } else { + rrc->active_RLC_entity[lcid] = true; + AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n"); + AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING, + "Invalid RB for RLC configuration\n"); + if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { + NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; + nr_rlc_add_srb(rrc->ue_id, srb_id, rlc_bearer); + nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); + } else { // DRB + NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity; + if (!rlc_bearer->rlc_Config) { + LOG_E(RLC, "RLC-Config not present but is mandatory for setup\n"); + rrc->active_RLC_entity[lcid] = false; + } else { + nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer); + nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); + } + } + } + } + } +} + +static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc, + NR_ReconfigurationWithSync_t *reconfigurationWithSync, + int gNB_index) +{ + // perform Reconfiguration with sync according to 5.3.5.5.2 + if (!rrc->as_security_activated && !(get_softmodem_params()->phy_test || get_softmodem_params()->do_ra)) { + // if the AS security is not activated, perform the actions upon going to RRC_IDLE as specified in 5.3.11 + // with the release cause 'other' upon which the procedure ends + NR_Release_Cause_t release_cause = OTHER; + nr_rrc_going_to_IDLE(rrc, release_cause, NULL); + return; + } + + if (reconfigurationWithSync->spCellConfigCommon) { + /* if the frequencyInfoDL is included, consider the target SpCell + to be one on the SSB frequency indicated by the frequencyInfoDL */ + const NR_DownlinkConfigCommon_t *dcc = reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon; + if (dcc && dcc->frequencyInfoDL && dcc->frequencyInfoDL->absoluteFrequencySSB) { + rrc->arfcn_ssb = *dcc->frequencyInfoDL->absoluteFrequencySSB; + LOG_I(NR_RRC, "UE %ld: updated ARFCN_SSB=%ld\n", rrc->ue_id, rrc->arfcn_ssb); + } + + // consider the target SpCell to be one with a physical cell identity indicated by the physCellId + if (!reconfigurationWithSync->spCellConfigCommon->physCellId) + LOG_E(NR_RRC, "physCellId absent but should be mandatory present upon cell change and cell addition\n"); + else + rrc->phyCellID = *reconfigurationWithSync->spCellConfigCommon->physCellId; + } + + NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; + nr_timer_stop(&tac->T310); + if (!get_softmodem_params()->phy_test) { + // T304 is stopped upon completion of RA procedure which is not done in phy-test mode + int t304_value = nr_rrc_get_T304(reconfigurationWithSync->t304); + nr_timer_setup(&tac->T304, t304_value, 10); // 10ms step + nr_timer_start(&tac->T304); + } + rrc->rnti = reconfigurationWithSync->newUE_Identity; + // reset the MAC entity of this cell group (done at MAC in handle_reconfiguration_with_sync) + + // 3GPP TS38.331 section 5.3.5.5.2 + nr_timer_stop(&tac->T430); + + if (rrc->target_ntncfg) { + ASN_STRUCT_FREE(asn_DEF_NR_NTN_Config_r17, rrc->target_ntncfg); + rrc->target_ntncfg = NULL; + rrc->process_target_ntncfg = false; + } + if (reconfigurationWithSync->spCellConfigCommon && + reconfigurationWithSync->spCellConfigCommon->ext2 && + reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17) { + NR_NTN_Config_r17_t *ntncfg = reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17; + // EPOCH time is always sent if NTN config is sent through DCCH + AssertFatal(ntncfg->epochTime_r17, "NTN-CONFIG sent in dedicated mode should have EPOCHTIME\n"); + const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **)&rrc->target_ntncfg, ntncfg); + AssertFatal(copy_result == 0, "unable to copy NR_NTN_Config_r17_t\n"); + } +} + +static void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cgConfig, int gNB_index, bool dedicatedsib1) +{ + NR_SpCellConfig_t *spCellConfig = cgConfig->spCellConfig; + if(spCellConfig) { + NR_ServingCellConfig_t *spCellConfigDedicated = spCellConfig->spCellConfigDedicated; + if (spCellConfigDedicated) { + if (spCellConfigDedicated->firstActiveDownlinkBWP_Id) + rrc->dl_bwp_id = *spCellConfigDedicated->firstActiveDownlinkBWP_Id; + if (spCellConfigDedicated->uplinkConfig && spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id) + rrc->ul_bwp_id = *spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id; + } + NR_ReconfigurationWithSync_t *reconfigurationWithSync = spCellConfig->reconfigurationWithSync; + if (reconfigurationWithSync) { + LOG_I(NR_RRC, "Processing reconfigurationWithSync\n"); + nr_rrc_process_reconfigurationWithSync(rrc, reconfigurationWithSync, gNB_index); + // if RRCReconfiguration does not include dedicatedSIB1-Delivery + // if the active downlink BWP, which is indicated by the firstActiveDownlinkBWP-Id for the target SpCell of the MCG, + // has a common search space configured by searchSpaceSIB1 + // acquire the SIB1, which is scheduled as specified in TS 38.213 [13], of the target SpCell of the MCG + if (!dedicatedsib1 && IS_SA_MODE(get_softmodem_params())) { + if (rrc->dl_bwp_id == 0) { + // Check initial DL BWP for searchSpaceSIB1 + NR_ServingCellConfigCommon_t *spCellConfigCommon = reconfigurationWithSync->spCellConfigCommon; + if (spCellConfigCommon) { + NR_DownlinkConfigCommon_t *downlinkConfig = spCellConfigCommon->downlinkConfigCommon; + if (downlinkConfig + && downlinkConfig->initialDownlinkBWP + && downlinkConfig->initialDownlinkBWP->pdcch_ConfigCommon + && downlinkConfig->initialDownlinkBWP->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup + && downlinkConfig->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1) { + rrc->sched_reconfsync_sib1 = true; + } + } + } else { + // Check dedicated DL BWP for searchSpaceSIB1 + if (spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { + for (int i = 0; i < spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; i++) { + NR_BWP_Downlink_t *bwp = spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i]; + if (bwp->bwp_Id == rrc->dl_bwp_id && bwp->bwp_Common && bwp->bwp_Common->pdcch_ConfigCommon + && bwp->bwp_Common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup + && bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1) { + rrc->sched_reconfsync_sib1 = true; + break; + } + } + } + } + } + } + nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spCellConfig->rlf_TimersAndConstants); + } + + nr_rrc_manage_rlc_bearers(rrc, cgConfig); + + if (cgConfig->ext1) + AssertFatal(cgConfig->ext1->reportUplinkTxDirectCurrent == NULL, "Reporting of UplinkTxDirectCurrent not implemented\n"); + AssertFatal(cgConfig->sCellToReleaseList == NULL, "Secondary serving cell release not implemented\n"); + AssertFatal(cgConfig->sCellToAddModList == NULL, "Secondary serving cell addition not implemented\n"); +} + static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, OCTET_STRING_t *masterCellGroup, long *fullConfig, @@ -768,7 +1060,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); } - nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index); + nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index, false); LOG_D(RRC, "Sending CellGroupConfig to MAC the pointer will be managed by mac\n"); nr_mac_rrc_message_t rrc_msg = {0}; @@ -776,10 +1068,12 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, nr_mac_rrc_config_cg_t *mac_msg = &rrc_msg.payload.config_cg; mac_msg->cellGroupConfig = cellGroupConfig; mac_msg->UE_NR_Capability = rrc->UECap.UE_NR_Capability; + mac_msg->hfn = rrc->current_hfn; + mac_msg->frame = rrc->current_frame; nr_rrc_send_msg_to_mac(rrc, &rrc_msg); } -static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCReconfiguration_v1530_IEs_t *rec_1530, int gNB_index) +static bool nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCReconfiguration_v1530_IEs_t *rec_1530, int gNB_index) { if (rec_1530->fullConfig) { // TODO perform the full configuration procedure as specified in 5.3.5.11 of 331 @@ -793,7 +1087,9 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe nr_pdcp_config_set_security(rrc->ue_id, 1, true, &sp); } NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; + bool dedicatedsib1 = false; if (rec_1530->dedicatedSIB1_Delivery) { + dedicatedsib1 = true; NR_SIB1_t *sib1 = NULL; asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_SIB1, @@ -824,7 +1120,7 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe SEQUENCE_free(&asn_DEF_NR_SystemInformation, si, 1); } else { LOG_I(NR_RRC, "[UE %ld] Decoding dedicatedSystemInformationDelivery\n", rrc->ue_id); - nr_decode_SI(SI_info, si, rrc, rrc->current_frame); + nr_decode_SI(SI_info, si, rrc, rrc->current_hfn, rrc->current_frame); } } if (rec_1530->otherConfig) { @@ -860,6 +1156,7 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe } } } + return dedicatedsib1; } static void handle_meas_reporting_remove(rrcPerNB_t *rrc, int id, NR_UE_Timers_Constants_t *timers) @@ -1138,8 +1435,9 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_ case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: { NR_RRCReconfiguration_IEs_t *ie = reconfiguration->criticalExtensions.choice.rrcReconfiguration; + bool dedicatedsib1 = false; if (ie->nonCriticalExtension) - nr_rrc_process_reconfiguration_v1530(rrc, ie->nonCriticalExtension, gNB_index); + dedicatedsib1 = nr_rrc_process_reconfiguration_v1530(rrc, ie->nonCriticalExtension, gNB_index); if (ie->radioBearerConfig) { LOG_I(NR_RRC, "RRCReconfiguration includes radio Bearer Configuration\n"); @@ -1175,13 +1473,15 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_ if (LOG_DEBUGFLAG(DEBUG_ASN1)) xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig); - nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index); + nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index, dedicatedsib1); AssertFatal(!IS_SA_MODE(get_softmodem_params()), "secondaryCellGroup only used in NSA for now\n"); nr_mac_rrc_message_t rrc_msg = {0}; rrc_msg.payload_type = NR_MAC_RRC_CONFIG_CG; nr_mac_rrc_config_cg_t *config_cg = &rrc_msg.payload.config_cg; config_cg->cellGroupConfig = cellGroupConfig; config_cg->UE_NR_Capability = rrc->UECap.UE_NR_Capability; + config_cg->hfn = rrc->current_hfn; + config_cg->frame = rrc->current_frame; nr_rrc_send_msg_to_mac(rrc, &rrc_msg); } } @@ -1278,6 +1578,7 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int instance_id, int num_ant_ rrc->dl_bwp_id = 0; rrc->ul_bwp_id = 0; rrc->as_security_activated = false; + rrc->sched_reconfsync_sib1 = false; rrc->detach_after_release = false; rrc->reconfig_after_reestab = false; /* 5G-S-TMSI */ @@ -1468,6 +1769,15 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, } NR_BCCH_BCH_Message_t *bcch_message = NULL; + if (rrc->phyCellID != phycellid || rrc->arfcn_ssb != ssb_arfcn) { + LOG_I(NR_RRC, + "[UE %ld] BCCH update: phyCellID %d->%u, arfcn_ssb %ld->%ld\n", + rrc->ue_id, + rrc->phyCellID, + phycellid, + rrc->arfcn_ssb, + ssb_arfcn); + } rrc->phyCellID = phycellid; rrc->arfcn_ssb = ssb_arfcn; @@ -1507,17 +1817,21 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc, && rrc->nrRrcState != RRC_STATE_DETACH_NR) { // to schedule MAC to get SI if required get_sib = check_si_status(SI_info); - if (get_sib) - SI_info->sib_pending = true; } if (bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib) { nr_mac_rrc_message_t rrc_msg = {0}; rrc_msg.payload_type = NR_MAC_RRC_CONFIG_MIB; nr_mac_rrc_config_mib_t *config_mib = &rrc_msg.payload.config_mib; config_mib->bcch = bcch_message; - config_mib->get_sib = get_sib; config_mib->access_barred = barred; nr_rrc_send_msg_to_mac(rrc, &rrc_msg); + if (get_sib) { + SI_info->sib_pending = true; + nr_mac_rrc_message_t sib_msg = {0}; + sib_msg.payload_type = NR_MAC_RRC_SCHED_SIB; + sib_msg.payload.sched_sib.get_sib = get_sib; + nr_rrc_send_msg_to_mac(rrc, &sib_msg); + } } else { LOG_E(NR_RRC, "RRC-received BCCH message is not a MIB\n"); ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message); @@ -1611,6 +1925,7 @@ static void nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, const uint8_t Sdu_len, const uint8_t rsrq, const uint8_t rsrp, + int hfn, int frame, int slot) { @@ -1650,7 +1965,7 @@ static void nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: LOG_I(NR_RRC, "[UE %ld] %d:%d Decoding SI\n", rrc->ue_id, frame, slot); NR_SystemInformation_t *si = bcch_message->message.choice.c1->choice.systemInformation; - nr_decode_SI(SI_info, si, rrc, frame); + nr_decode_SI(SI_info, si, rrc, hfn, frame); break; case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: default: @@ -1661,155 +1976,6 @@ static void nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); } -static void nr_rrc_signal_maxrtxindication(int ue_id) -{ - MessageDef *msg = itti_alloc_new_message(TASK_RLC_UE, ue_id, NR_RRC_RLC_MAXRTX); - NR_RRC_RLC_MAXRTX(msg).ue_id = ue_id; - itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, msg); -} - -/** @brief Release all active RLC entities for a UE and set to inactive. - * This is typically used when tearing down all DRBs at UE side, - * such as after a PDU session release or full reconfiguration. - * @param rrc Pointer to NR_UE_RRC_INST_t structure - * @param id Logical Channel ID (must be in range [0, NR_MAX_NUM_LCID-1]) */ -static void nr_rrc_release_rlc_entity(NR_UE_RRC_INST_t *rrc, int id) -{ - DevAssert(rrc); - DevAssert(id >= 0 && id < NR_MAX_NUM_LCID); - if (rrc->active_RLC_entity[id]) { - rrc->active_RLC_entity[id] = false; - nr_rlc_release_entity(rrc->ue_id, id); - LOG_I(RLC, "Released RLC entity: ue_id=%ld, lc_id=%d\n", rrc->ue_id, id); - } -} - -static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, const NR_CellGroupConfig_t *cellGroupConfig) -{ - if (cellGroupConfig->rlc_BearerToReleaseList != NULL) { - for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) { - NR_LogicalChannelIdentity_t *lcid = cellGroupConfig->rlc_BearerToReleaseList->list.array[i]; - AssertFatal(lcid, "LogicalChannelIdentity shouldn't be null here\n"); - nr_rrc_release_rlc_entity(rrc, *lcid); - } - } - - if (cellGroupConfig->rlc_BearerToAddModList != NULL) { - for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) { - NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i]; - NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity; - if (rrc->active_RLC_entity[lcid]) { - if (rlc_bearer->reestablishRLC) - nr_rlc_reestablish_entity(rrc->ue_id, lcid); - if (rlc_bearer->rlc_Config) - nr_rlc_reconfigure_entity(rrc->ue_id, lcid, rlc_bearer->rlc_Config); - } else { - rrc->active_RLC_entity[lcid] = true; - AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n"); - AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING, - "Invalid RB for RLC configuration\n"); - if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { - NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; - nr_rlc_add_srb(rrc->ue_id, srb_id, rlc_bearer); - nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); - } else { // DRB - NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity; - if (!rlc_bearer->rlc_Config) { - LOG_E(RLC, "RLC-Config not present but is mandatory for setup\n"); - rrc->active_RLC_entity[lcid] = false; - } else { - nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer); - nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); - } - } - } - } - } -} - -static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc, - NR_ReconfigurationWithSync_t *reconfigurationWithSync, - int gNB_index) -{ - // perform Reconfiguration with sync according to 5.3.5.5.2 - if (!rrc->as_security_activated && !(get_softmodem_params()->phy_test || get_softmodem_params()->do_ra)) { - // if the AS security is not activated, perform the actions upon going to RRC_IDLE as specified in 5.3.11 - // with the release cause 'other' upon which the procedure ends - NR_Release_Cause_t release_cause = OTHER; - nr_rrc_going_to_IDLE(rrc, release_cause, NULL); - return; - } - - if (reconfigurationWithSync->spCellConfigCommon) { - /* if the frequencyInfoDL is included, consider the target SpCell - to be one on the SSB frequency indicated by the frequencyInfoDL */ - const NR_DownlinkConfigCommon_t *dcc = reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon; - if (dcc && dcc->frequencyInfoDL && dcc->frequencyInfoDL->absoluteFrequencySSB) - rrc->arfcn_ssb = *dcc->frequencyInfoDL->absoluteFrequencySSB; - - // consider the target SpCell to be one with a physical cell identity indicated by the physCellId - if (!reconfigurationWithSync->spCellConfigCommon->physCellId) - LOG_E(NR_RRC, "physCellId absent but should be mandatory present upon cell change and cell addition\n"); - else - rrc->phyCellID = *reconfigurationWithSync->spCellConfigCommon->physCellId; - } - - NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants; - nr_timer_stop(&tac->T310); - if (!get_softmodem_params()->phy_test) { - // T304 is stopped upon completion of RA procedure which is not done in phy-test mode - int t304_value = nr_rrc_get_T304(reconfigurationWithSync->t304); - nr_timer_setup(&tac->T304, t304_value, 10); // 10ms step - nr_timer_start(&tac->T304); - } - rrc->rnti = reconfigurationWithSync->newUE_Identity; - // reset the MAC entity of this cell group (done at MAC in handle_reconfiguration_with_sync) - - // 3GPP TS38.331 section 5.3.5.5.2 - nr_timer_stop(&tac->T430); - - if (rrc->target_ntncfg) { - ASN_STRUCT_FREE(asn_DEF_NR_NTN_Config_r17, rrc->target_ntncfg); - rrc->target_ntncfg = NULL; - rrc->process_target_ntncfg = false; - } - if (reconfigurationWithSync->spCellConfigCommon && - reconfigurationWithSync->spCellConfigCommon->ext2 && - reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17) { - NR_NTN_Config_r17_t *ntncfg = reconfigurationWithSync->spCellConfigCommon->ext2->ntn_Config_r17; - // EPOCH time is always sent if NTN config is sent through DCCH - AssertFatal(ntncfg->epochTime_r17, "NTN-CONFIG sent in dedicated mode should have EPOCHTIME\n"); - const int copy_result = asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **)&rrc->target_ntncfg, ntncfg); - AssertFatal(copy_result == 0, "unable to copy NR_NTN_Config_r17_t\n"); - } -} - -void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig, int gNB_index) -{ - NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig; - if(spCellConfig) { - if (spCellConfig->reconfigurationWithSync) { - LOG_I(NR_RRC, "Processing reconfigurationWithSync\n"); - nr_rrc_process_reconfigurationWithSync(rrc, spCellConfig->reconfigurationWithSync, gNB_index); - } - nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spCellConfig->rlf_TimersAndConstants); - if (spCellConfig->spCellConfigDedicated) { - if (spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id) - rrc->dl_bwp_id = *spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id; - if (spCellConfig->spCellConfigDedicated->uplinkConfig && - spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id) - rrc->dl_bwp_id = *spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id; - } - } - - nr_rrc_manage_rlc_bearers(rrc, cellGroupConfig); - - if (cellGroupConfig->ext1) - AssertFatal(cellGroupConfig->ext1->reportUplinkTxDirectCurrent == NULL, "Reporting of UplinkTxDirectCurrent not implemented\n"); - AssertFatal(cellGroupConfig->sCellToReleaseList == NULL, "Secondary serving cell release not implemented\n"); - AssertFatal(cellGroupConfig->sCellToAddModList == NULL, "Secondary serving cell addition not implemented\n"); -} - static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const uint8_t Transaction_id) { uint8_t buffer[100]; @@ -2196,6 +2362,9 @@ static void nr_rrc_ue_generate_rrcReestablishmentComplete(const NR_UE_RRC_INST_t nr_pdcp_data_req_srb(rrc->ue_id, srb_id, 0, size, buffer, deliver_pdu_srb_rlc, NULL); } +/** @brief Process RRCReestablishment message + * This function processes the RRCReestablishment message received from the gNB, + * implementing procedures as described in 38.331 section 5.3.7.5 */ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, const int gNB_index, const NR_RRCReestablishment_t *rrcReestablishment, @@ -2204,18 +2373,19 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, int msg_size, const nr_pdcp_integrity_data_t *msg_integrity) { - // implementign procedues as described in 38.331 section 5.3.7.5 // stop timer T301 NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; nr_timer_stop(&timers->T301); - // store the nextHopChainingCount value NR_RRCReestablishment_IEs_t *ies = rrcReestablishment->criticalExtensions.choice.rrcReestablishment; AssertFatal(ies, "Not expecting RRCReestablishment_IEs to be NULL\n"); - // TODO need to understand how to use nextHopChainingCount - // int nh = rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount; - // update the K gNB key based on the current K gNB key or the NH, using the stored nextHopChainingCount value - nr_derive_key_ng_ran_star(rrc->phyCellID, rrc->arfcn_ssb, rrc->kgnb, rrc->kgnb); + // Update KgNB based on the current K gNB key or the NH, + // using the received nextHopChainingCount (per 33.501 6.9.2.3.4) + // received from RRCReestablishment and update the stored value in rrc->nhcc + int8_t received_ncc = ies->nextHopChainingCount; + nr_ue_nas_t *nas = get_ue_nas_info(rrc->ue_id); + const uint8_t *kamf = nas->security.kamf; + nr_update_kgnb_from_ncc(rrc, kamf, received_ncc); // derive the K_RRCenc key associated with the previously configured cipheringAlgorithm // derive the K_RRCint key associated with the previously configured integrityProtAlgorithm @@ -2237,6 +2407,7 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc, // perform the actions upon going to RRC_IDLE as specified in 5.3.11 // with release cause 'RRC connection failure', upon which the procedure ends if (!integrity_pass) { + LOG_W(NR_RRC, "Integrity of RRCReestablishment failed, going to IDLE\n"); NR_Release_Cause_t release_cause = RRC_CONNECTION_FAILURE; nr_rrc_going_to_IDLE(rrc, release_cause, NULL); return; @@ -2585,14 +2756,37 @@ static void nr_ue_check_meas_report(NR_UE_RRC_INST_t *rrc, const uint8_t gnb_ind } } -void nr_rrc_handle_ra_indication(NR_UE_RRC_INST_t *rrc, bool ra_succeeded) +static void nr_rrc_handle_ra_indication(NR_UE_RRC_INST_t *rrc, bool ra_succeeded, int gNB_index) { NR_UE_Timers_Constants_t *timers = &rrc->timers_and_constants; if (ra_succeeded && nr_timer_is_active(&timers->T304)) { // successful Random Access procedure triggered by reconfigurationWithSync - nr_timer_stop(&timers->T304); - // TODO handle the rest of procedures as described in 5.3.5.3 for when + // procedures described in 5.3.5.3 of 38.331 when // reconfigurationWithSync is included in spCellConfig + nr_timer_stop(&timers->T304); + + // TODO apply the parts of the CQI reporting configuration, + // the scheduling request configuration and the sounding RS + // configuration that do not require the UE to know the SFN of the respective target SpCell + // TODO apply the parts of the measurement and the radio resource configuration + // that require the UE to know the SFN of the respective target SpCell + // (not sure what to do for these two points, probably not relevant for our implementation) + + // if T390 is running stop timer T390 for all access categories + if (nr_timer_is_active(&timers->T390)) { + nr_timer_stop(&timers->T390); + // TODO perform the actions as specified in 5.3.14.4. + } + + if (rrc->sched_reconfsync_sib1) { + rrc->sched_reconfsync_sib1 = false; + NR_UE_RRC_SI_INFO *SI_info = &rrc->perNB[gNB_index].SInfo; + SI_info->sib_pending = true; + nr_mac_rrc_message_t sib_msg = {0}; + sib_msg.payload_type = NR_MAC_RRC_SCHED_SIB; + sib_msg.payload.sched_sib.get_sib = 1; + nr_rrc_send_msg_to_mac(rrc, &sib_msg); + } } else if (!ra_succeeded) { // upon random access problem indication from MCG MAC // while neither T300, T301, T304, T311 nor T319 are running @@ -2640,6 +2834,7 @@ void *rrc_nrue(void *notUsed) } break; case NRRRC_FRAME_PROCESS: + rrc->current_hfn = NRRRC_FRAME_PROCESS(msg_p).hfn; rrc->current_frame = NRRRC_FRAME_PROCESS(msg_p).frame; LOG_D(NR_RRC, "Received %s: frame %d\n", ITTI_MSG_NAME(msg_p), rrc->current_frame); // increase the timers every 10ms (every new frame) @@ -2683,7 +2878,7 @@ void *rrc_nrue(void *notUsed) rrc->ue_id, ITTI_MSG_NAME(msg_p), NR_RRC_MAC_RA_IND(msg_p).RA_succeeded ? "successful" : "failed"); - nr_rrc_handle_ra_indication(rrc, NR_RRC_MAC_RA_IND(msg_p).RA_succeeded); + nr_rrc_handle_ra_indication(rrc, NR_RRC_MAC_RA_IND(msg_p).RA_succeeded, NR_RRC_MAC_RA_IND(msg_p).gnb_index); break; case NR_RRC_MAC_BCCH_DATA_IND: @@ -2698,6 +2893,7 @@ void *rrc_nrue(void *notUsed) bcch->sdu_size, bcch->rsrq, bcch->rsrp, + bcch->hfn, bcch->frame, bcch->slot); break; diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 0672af7741..336afcc63a 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -262,8 +262,9 @@ typedef struct NR_UE_RRC_INST_s { // 5G-S-TMSI uint64_t fiveG_S_TMSI; // Frame timing received from MAC + int current_hfn; int current_frame; - + bool sched_reconfsync_sib1; //Sidelink params NR_SL_PreconfigurationNR_r16_t *sl_preconfig; // NTN params diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 1ebb728884..d8f2c0f23f 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -46,9 +46,6 @@ NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance); void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfig_file); void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len); - -void nr_rrc_cellgroup_configuration(NR_UE_RRC_INST_t *rrc, NR_CellGroupConfig_t *cellGroupConfig, int gNB_index); - void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, NR_Release_Cause_t release_cause, NR_RRCRelease_t *RRCRelease); @@ -73,7 +70,7 @@ int get_from_lte_ue_fd(); void nr_rrc_SI_timers(NR_UE_RRC_SI_INFO *SInfo); void init_SI_timers(NR_UE_RRC_SI_INFO *SInfo); -void nr_ue_rrc_timer_trigger(int module_id, int frame, int gnb_id); +void nr_ue_rrc_timer_trigger(int module_id, int hfn, int frame, int gnb_id); void handle_t300_expiry(NR_UE_RRC_INST_t *rrc); void handle_t430_expiry(NR_UE_RRC_INST_t *rrc); diff --git a/openair3/NGAP/ngap_gNB_context_management_procedures.c b/openair3/NGAP/ngap_gNB_context_management_procedures.c index 7f114d5bf6..57b7780d4f 100644 --- a/openair3/NGAP/ngap_gNB_context_management_procedures.c +++ b/openair3/NGAP/ngap_gNB_context_management_procedures.c @@ -191,7 +191,7 @@ int ngap_ue_context_release_req(instance_t instance, for (int i = 0; i < ue_release_req_p->nb_of_pdusessions; i++) { NGAP_PDUSessionResourceItemCxtRelReq_t *item; item = (NGAP_PDUSessionResourceItemCxtRelReq_t *)calloc(1,sizeof(NGAP_PDUSessionResourceItemCxtRelReq_t)); - item->pDUSessionID = ue_release_req_p->pdusessions[i].pdusession_id; + item->pDUSessionID = ue_release_req_p->pdusession_ids[i]; asn1cSeqAdd(&ie->value.choice.PDUSessionResourceListCxtRelReq.list, item); } } diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 95c2dd45a7..292ab1635d 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -84,7 +84,6 @@ void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shut } } } else { - LOG_A(NGAP, "Received NGSetupResponse from AMF\n"); /* Check that at least one setup message is pending */ DevCheck(amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb > 0, amf_desc_p->ngap_gNB_instance->instance, amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb, 0); @@ -314,6 +313,7 @@ static int ngap_gNB_handle_ng_setup_response(sctp_assoc_t assoc_id, uint32_t str amf_desc_p->state = NGAP_GNB_STATE_CONNECTED; amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb ++; ngap_handle_ng_setup_message(amf_desc_p, 0); + LOG_A(NGAP, "Received NGSetupResponse from AMF\n"); return 0; } @@ -849,6 +849,11 @@ static int ngap_gNB_handle_initial_context_request(sctp_assoc_t assoc_id, uint32 itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); + NGAP_INFO("Initial Context Setup UE RAN ID %d UE AMF ID %ld: %d PDU session(s)\n", + msg->gNB_ue_ngap_id, + msg->amf_ue_ngap_id, + msg->nb_of_pdusessions); + return 0; } @@ -1390,9 +1395,20 @@ static int ngap_gNB_handle_pdusession_release_command(sctp_assoc_t assoc_id, uin for (i = 0; i < ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; i++) { NGAP_PDUSessionResourceToReleaseItemRelCmd_t *item_p; item_p = ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i]; - pdusession_release_t *r = &msg->pdusession_release_params[i]; - r->pdusession_id = item_p->pDUSessionID; - r->data = create_byte_array(item_p->pDUSessionResourceReleaseCommandTransfer.size, item_p->pDUSessionResourceReleaseCommandTransfer.buf); + msg->pdusession_ids[i] = item_p->pDUSessionID; + + /* PDUSessionResourceReleaseCommandTransfer (Mandatory) */ + void *decoded = decode_pdusession_transfer(&asn_DEF_NGAP_PDUSessionResourceReleaseCommandTransfer, + item_p->pDUSessionResourceReleaseCommandTransfer); + if (!decoded) { + NGAP_ERROR("Failed to decode PDUSessionResourceReleaseCommandTransfer for PDU Session %d\n", msg->pdusession_ids[i]); + return -1; + } + NGAP_PDUSessionResourceReleaseCommandTransfer_t *transfer = decoded; + ngap_cause_t cause = decode_ngap_cause(&transfer->cause); + NGAP_INFO("PDU Session %d release command: Cause type=%d value=%d\n", msg->pdusession_ids[i], cause.type, cause.value); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceReleaseCommandTransfer, transfer); + free(transfer); } itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); diff --git a/openair3/NGAP/ngap_gNB_itti_messaging.c b/openair3/NGAP/ngap_gNB_itti_messaging.c index b640f2e556..1e03192599 100644 --- a/openair3/NGAP/ngap_gNB_itti_messaging.c +++ b/openair3/NGAP/ngap_gNB_itti_messaging.c @@ -54,7 +54,7 @@ void ngap_gNB_itti_send_sctp_data_req(instance_t instance, itti_send_msg_to_task(TASK_SCTP, instance, message_p); } -void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ngap_id, uint8_t *nas_pdu, uint32_t nas_pdu_length) +void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ngap_id, uint64_t amf_ue_ngap_id, uint8_t *nas_pdu, uint32_t nas_pdu_length) { MessageDef *message_p; ngap_downlink_nas_t *ngap_downlink_nas; @@ -64,6 +64,7 @@ void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ng ngap_downlink_nas = &message_p->ittiMsg.ngap_downlink_nas; ngap_downlink_nas->gNB_ue_ngap_id = gNB_ue_ngap_id; + ngap_downlink_nas->amf_ue_ngap_id = amf_ue_ngap_id; ngap_downlink_nas->nas_pdu = create_byte_array(nas_pdu_length, nas_pdu); itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); diff --git a/openair3/NGAP/ngap_gNB_itti_messaging.h b/openair3/NGAP/ngap_gNB_itti_messaging.h index 67054761e3..09ae4d6480 100644 --- a/openair3/NGAP/ngap_gNB_itti_messaging.h +++ b/openair3/NGAP/ngap_gNB_itti_messaging.h @@ -40,7 +40,11 @@ void ngap_gNB_itti_send_sctp_data_req(instance_t instance, uint32_t buffer_length, uint16_t stream); -void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ngap_id, uint8_t *nas_pdu, uint32_t nas_pdu_length); +void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, + uint32_t gNB_ue_ngap_id, + uint64_t amf_ue_ngap_id, + uint8_t *nas_pdu, + uint32_t nas_pdu_length); void ngap_gNB_itti_send_sctp_close_association(instance_t instance, sctp_assoc_t assoc_id); diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 7dd6359b7a..7bf7753668 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -361,7 +361,11 @@ int ngap_gNB_handle_nas_downlink(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NG 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->gNB_ue_ngap_id, ie->value.choice.NAS_PDU.buf, ie->value.choice.NAS_PDU.size); + ngap_gNB_itti_send_nas_downlink_ind(ngap_gNB_instance->instance, + ue_desc_p->gNB_ue_ngap_id, + ue_desc_p->amf_ue_ngap_id, + ie->value.choice.NAS_PDU.buf, + ie->value.choice.NAS_PDU.size); return 0; } @@ -594,6 +598,24 @@ static byte_array_t encode_ngap_pdusession_setup_response_transfer(const pdusess return out; } +/** @brief PDU Session Resource Release Response Transfer encoding (9.3.4.21 3GPP TS 38.413) + * The transfer structure contains only an optional Secondary RAT Usage Information IE. + * Since we don't use secondary RAT (MR-DC), we encode an empty structure. */ +static byte_array_t encode_ngap_pdusession_release_response_transfer(void) +{ + NGAP_PDUSessionResourceReleaseResponseTransfer_t pdusessionTransfer = {0}; + + // Encode + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, + ATS_ALIGNED_CANONICAL_PER, + &asn_DEF_NGAP_PDUSessionResourceReleaseResponseTransfer, + &pdusessionTransfer); + AssertFatal(res.buffer, "ASN1 message encoding failed (%s, %lu)!\n", res.result.failed_type->name, res.result.encoded); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceReleaseResponseTransfer, &pdusessionTransfer); + byte_array_t out = {.buf = res.buffer, .len = res.result.encoded}; + return out; +} + //------------------------------------------------------------------------------ int ngap_gNB_initial_ctxt_resp(instance_t instance, ngap_initial_context_setup_resp_t *initial_ctxt_resp_p) //------------------------------------------------------------------------------ @@ -1200,22 +1222,28 @@ int ngap_gNB_pdusession_release_resp(instance_t instance, ngap_pdusession_releas ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id; } - /* optional */ - if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) { + /* PDU Session Resource Released List (mandatory) */ + { asn1cSequenceAdd(out->protocolIEs.list, NGAP_PDUSessionResourceReleaseResponseIEs_t, ie); 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++) { - asn1cSequenceAdd(ie->value.choice.PDUSessionResourceReleasedListRelRes.list, NGAP_PDUSessionResourceReleasedItemRelRes_t, item); + NGAP_PDUSessionResourceReleasedListRelRes_t *list = &ie->value.choice.PDUSessionResourceReleasedListRelRes; + asn1cSequenceAdd(list->list, NGAP_PDUSessionResourceReleasedItemRelRes_t, item); pdusession_release_t *r = &pdusession_release_resp_p->pdusession_release[i]; + /* PDU Session ID (mandatory) */ item->pDUSessionID = r->pdusession_id; - OCTET_STRING_fromBuf(&item->pDUSessionResourceReleaseResponseTransfer, (const char *)r->data.buf, r->data.len); - NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID); + /* PDU Session Resource Release Response Transfer (mandatory) */ + // Empty transfer is valid since Secondary RAT Usage Information is optional and not used + byte_array_t transfer = encode_ngap_pdusession_release_response_transfer(); + OCTET_STRING_fromBuf(&item->pDUSessionResourceReleaseResponseTransfer, (const char *)transfer.buf, transfer.len); + free_byte_array(transfer); + NGAP_DEBUG("PDU Session Resource Release Response: pdusession ID %ld\n", item->pDUSessionID); } } - + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { NGAP_ERROR("Failed to encode release response\n"); /* Encode procedure has failed... */ diff --git a/openair3/NGAP/ngap_msg_includes.h b/openair3/NGAP/ngap_msg_includes.h index 816cdfb979..2a861e2e32 100644 --- a/openair3/NGAP/ngap_msg_includes.h +++ b/openair3/NGAP/ngap_msg_includes.h @@ -58,6 +58,8 @@ #include "NGAP_PDUSessionResourceSetupResponseTransfer.h" #include "NGAP_PDUSessionResourceSetupUnsuccessfulTransfer.h" #include "NGAP_PDUSessionResourceToReleaseItemRelCmd.h" +#include "NGAP_PDUSessionResourceReleaseCommandTransfer.h" +#include "NGAP_PDUSessionResourceReleaseResponseTransfer.h" #include "NGAP_PLMNSupportItem.h" #include "NGAP_ProtocolIE-Field.h" #include "NGAP_QosFlowAddOrModifyResponseItem.h" diff --git a/openair3/SECU/key_nas_deriver.c b/openair3/SECU/key_nas_deriver.c index 3fb35adee2..a2948ab0b2 100644 --- a/openair3/SECU/key_nas_deriver.c +++ b/openair3/SECU/key_nas_deriver.c @@ -150,8 +150,23 @@ void nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t * NOTE: knas is dynamically allocated by the KDF function */ -/** @brief KgNB derivation (A.9 3GPP TS 33.501) */ -void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb) +/** @brief KgNB derivation function (Annex A.9 3GPP TS 33.501) + * + * Derives KgNB from K_AMF and the uplink NAS COUNT. + * This function is applied when cryptographically protected 5G radio bearers are + * established and when a key change on-the-fly is performed. + * + * KDF input S structure (per Annex A.9): + * - FC = 0x6E + * - P0 = Uplink NAS COUNT (count parameter) + * - L0 = length of uplink NAS COUNT (0x00 0x04) + * - P1 = Access type distinguisher (0x01 for 3GPP access) + * - L1 = length of Access type distinguisher (0x00 0x01) + * + * @param[in] kamf 256-bit K_AMF key (input key KEY to KDF) + * @param[in] count Uplink NAS COUNT value (P0 in KDF input S) + * @param[out] kgnb Derived 256-bit KgNB key */ +void derive_kgnb(const uint8_t kamf[32], const uint32_t count, uint8_t *kgnb) { /* Compute the KDF input parameter * S = FC(0x6E) || UL NAS Count || 0x00 0x04 || 0x01 || 0x00 0x01 diff --git a/openair3/SECU/key_nas_deriver.h b/openair3/SECU/key_nas_deriver.h index eff72c68bb..100d554aa2 100644 --- a/openair3/SECU/key_nas_deriver.h +++ b/openair3/SECU/key_nas_deriver.h @@ -16,7 +16,7 @@ typedef enum { UP_INT_ALG = 0x06 } algorithm_type_dist_t; -void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb); +void derive_kgnb(const uint8_t kamf[32], const uint32_t count, uint8_t *kgnb); void derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB); diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index ed15d48f80..6650439e81 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -1036,9 +1036,9 @@ static int Gtpv1uHandleError(int h, uint8_t *msgBuf, uint32_t msgBufLen, const s " TV id for GTP addr %u (should be 133)\n" " len for addr of UPF %u (should be IPv4 or IPv6 len)" " (TS 29.281 Sec 7.3.1 Error Handling not implemented)\n", - msg->h.teid, + ntohl(msg->h.teid), msg->teid_data_i, - msg->teid, + ntohl(msg->teid), msg->addr_data_i, msg->addr_len); int rc = GTPNOK; diff --git a/radio/BLADERF/bladerf_lib.c b/radio/BLADERF/bladerf_lib.c index 178fc2fff2..bff12bee8e 100644 --- a/radio/BLADERF/bladerf_lib.c +++ b/radio/BLADERF/bladerf_lib.c @@ -957,8 +957,6 @@ int device_init(openair0_device *device, /* device specific */ //openair0_cfg->txlaunch_wait = 1;//manage when TX processing is triggered //openair0_cfg->txlaunch_wait_slotcount = 1; //manage when TX processing is triggered - openair0_cfg->iq_txshift = 0;// shift - openair0_cfg->iq_rxrescale = 15;//rescale iqs // init required params switch ((int)openair0_cfg->sample_rate) { @@ -983,8 +981,6 @@ int device_init(openair0_device *device, exit(-1); break; } - openair0_cfg->iq_txshift= 0; - openair0_cfg->iq_rxrescale = 15; /*not sure*/ openair0_cfg->rx_gain_calib_table = calib_table_fx4; // The number of buffers to use in the underlying data stream diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h index b87a6a8abf..5877506ea2 100644 --- a/radio/COMMON/common_lib.h +++ b/radio/COMMON/common_lib.h @@ -199,6 +199,8 @@ typedef struct split7_config { /*! this is the exponent in 2^X for the FFT size */ uint16_t fftSize; + /*! this is the ceil of the exponent in 2^X for the prach FFT size */ + uint16_t prach_fftSize; // M-plane related parameters uint16_t dl_k0[5]; uint16_t ul_k0[5]; @@ -274,10 +276,6 @@ typedef struct openair0_config { char *sdr_addrs; //! Auto calibration flag int autocal[8]; - //! rf devices work with x bits iqs when oai have its own iq format - //! the two following parameters are used to convert iqs - int iq_txshift; - int iq_rxrescale; //! Configuration file for LMS7002M char *configFilename; //! remote IP/MAC addr for Ethernet interface @@ -491,12 +489,29 @@ struct openair0_device_t { /*! \brief Called to send samples to the RF target @param device pointer to the device structure specific to the RF hardware target @param timestamp The timestamp at whicch the first sample MUST be sent - @param buff Buffer which holds the samples (2 dimensional) + @param buff Buffer which holds the samples (3 dimensional) @param nsamps number of samples to be sent - @param number of antennas + @param nb_antennas_tx number of antennas + @param num_beams number of beams @param flags flags must be set to true if timestamp parameter needs to be applied */ - int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags); + int (*trx_write_beams_func)(openair0_device *device, + openair0_timestamp timestamp, + void ***buff, + int nsamps, + int nb_antennas_tx, + int num_beams, + int flags); + + /*! \brief Called to send samples to the RF target + @param device pointer to the device structure specific to the RF hardware target + @param timestamp The timestamp at whicch the first sample MUST be sent + @param buff Buffer which holds the samples (2 dimensional) + @param nsamps number of samples to be sent + @param nb_antennas_tx number of antennas + @param flags flags must be set to true if timestamp parameter needs to be applied + */ + int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int nb_antennas_tx, int flags); /*! \brief Called to send samples to the RF target @param device pointer to the device structure specific to the RF hardware target @@ -518,7 +533,27 @@ struct openair0_device_t { * antennas from which to receive samples \returns the number of sample read */ - int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int num_antennas); + int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int num_antennas); + + /*! \brief Receive samples from hardware. + * Read nsamps samples from each channel to buffers. buff[0] is the array for + * the first channel. *ptimestamp is the time at which the first sample + * was received. + * \param device the hardware to use + * \param[out] ptimestamp the time at which the first sample was received. + * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of + * samples nsamps. + * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte. + * \param num_antennas number of antennas from which to receive samples + * \param num_beams number of beams from which to receive samples + * \returns the number of sample read + */ + int (*trx_read_beams_func)(openair0_device *device, + openair0_timestamp *ptimestamp, + void ***buff, + int nsamps, + int num_antennas, + int num_beams); /*! \brief Receive samples from hardware, this version provides a single antenna at a time and returns. * Read nsamps samples from each channel to buffers. buff[0] is the array for @@ -571,6 +606,37 @@ struct openair0_device_t { */ int (*trx_set_gains_func)(openair0_device *device, openair0_config_t *openair0_cfg); + /*! \brief Set tx/rx beams + * + * Set the tx/rx beams. This has to be done in advance of the reception in order to + * allow the underlying device to change receiver configuration. The exact time depends + * on the device. + * + * NOTICE: the samples returned from trx_read_func may belong to more than one beam. It is up + * to the application to determine the beam of the received samples. + * + * \param device the hardware to use + * \param beam_map the beams to receive + * \return 0 on success + */ + int (*trx_set_beams)(openair0_device *device, uint64_t beam_map, openair0_timestamp timestamp); + + /*! \brief Set tx/rx beams + * + * Set the tx/rx beams. This has to be done in advance of the reception in order to + * allow the underlying device to change receiver configuration. The exact time depends + * on the device. + * + * NOTICE: the samples returned from trx_read_func may belong to more than one beam. It is up + * to the application to determine the beam of the received samples. + * + * \param device the hardware to use + * \param beams pointer to array of beam ids + * \param num_beams number of beams + * \return 0 on success + */ + int (*trx_set_beams2)(openair0_device *device, int* beams, int num_beams, openair0_timestamp timestamp); + /*! \brief RRU Configuration callback * \param idx RU index * \param arg pointer to capabilities or configuration @@ -629,6 +695,7 @@ typedef struct { uint64_t timestamp; // Timestamp value of first sample uint32_t option_value; // Option value uint32_t option_flag; // Option flag + uint64_t beam_map; } samplesBlockHeader_t; #ifdef __cplusplus diff --git a/radio/ETHERNET/ethernet_lib.c b/radio/ETHERNET/ethernet_lib.c index 2a4d021afc..038246c998 100644 --- a/radio/ETHERNET/ethernet_lib.c +++ b/radio/ETHERNET/ethernet_lib.c @@ -540,40 +540,6 @@ int transport_init(openair0_device *device, eth->if_name = eth_params->local_if_name; device->priv = eth; - - - /* device specific */ - // openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - // openair0_cfg[0].iq_txshift = eth_params->iq_txshift;// shift - // openair0_cfg[0].tx_sample_advance = eth_params->tx_sample_advance; - - /* RRU does not have any information to make this configuration atm */ - /* - if (device->host_type == RAU_HOST) { - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - openair0_cfg[0].samples_per_packet = 3840; - break; - case 23040000: - openair0_cfg[0].samples_per_packet = 2880; - break; - case 15360000: - openair0_cfg[0].samples_per_packet = 1920; - break; - case 7680000: - openair0_cfg[0].samples_per_packet = 960; - break; - case 1920000: - openair0_cfg[0].samples_per_packet = 240; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - }*/ - device->openair0_cfg=&openair0_cfg[0]; return 0; } diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp index 923e938869..dabc6f8947 100644 --- a/radio/USRP/usrp_lib.cpp +++ b/radio/USRP/usrp_lib.cpp @@ -478,14 +478,15 @@ static int trx_usrp_write(openair0_device *device, nsamps2 = (nsamps+7)>>3; simde__m256i buff_tx[cc < 2 ? 2 : cc][nsamps2]; - // bring RX data into 12 LSBs for softmodem RX + // bring TX data into 16 MSBs, assuming it is on the 12 LSB after OAI computation + const int shift = 4; for (int i = 0; i < cc; i++) { for (int j = 0; j < nsamps2; j++) { if ((((uintptr_t)buff[i]) & 0x1F) == 0) { - buff_tx[i][j] = simde_mm256_slli_epi16(((simde__m256i *)buff[i])[j], 4); + buff_tx[i][j] = simde_mm256_slli_epi16(((simde__m256i *)buff[i])[j], shift); } else { simde__m256i tmp = simde_mm256_loadu_si256(((simde__m256i *)buff[i]) + j); - buff_tx[i][j] = simde_mm256_slli_epi16(tmp, 4); + buff_tx[i][j] = simde_mm256_slli_epi16(tmp, shift); } } } @@ -605,17 +606,17 @@ void *trx_usrp_write_thread(void * arg){ nsamps2 = (nsamps+7)>>3; simde__m256i buff_tx[cc < 2 ? 2 : cc][nsamps2]; - - // bring RX data into 12 LSBs for softmodem RX + // bring TX data into 16 MSBs, assuming it is on the 12 LSB after OAI computation + const int shift = 4; for (int i = 0; i < cc; i++) { for (int j = 0; j < nsamps2; j++) { if ((((uintptr_t) buff[i])&0x1F)==0) { - buff_tx[i][j] = simde_mm256_slli_epi16(((simde__m256i *)buff[i])[j], 4); + buff_tx[i][j] = simde_mm256_slli_epi16(((simde__m256i *)buff[i])[j], shift); } else { simde__m256i tmp = simde_mm256_loadu_si256(((simde__m256i *)buff[i]) + j); - buff_tx[i][j] = simde_mm256_slli_epi16(tmp,4); + buff_tx[i][j] = simde_mm256_slli_epi16(tmp, shift); } } } @@ -752,11 +753,13 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp // bring RX data into 12 LSBs for softmodem RX for (int i=0; itrx_read_func = emulator_read; emulator_readconfig(emulator_state); + if (emulator_state->enable_noise) + randominit(); // for noise device return 0; } diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index fb40852ebb..6e918650e5 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -17,7 +17,7 @@ add_library(oran_fhlib_5g MODULE ) set(E_VERSION 5.1.6) -set(F_VERSION 6.1.5) +set(F_VERSION 6.1.6) find_package(xran REQUIRED) if(xran_VERSION VERSION_EQUAL E_VERSION) diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index fcd908562a..7e0c105463 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -72,14 +72,6 @@ static void ly_print_clb(LY_LOG_LEVEL level, const char *msg, const char *path) } } -static const paramdef_t *gpd(const paramdef_t *pd, int num, const char *name) -{ - /* the config module does not know const-correctness... */ - int idx = config_paramidx_fromname((paramdef_t *)pd, num, (char *)name); - DevAssert(idx >= 0); - return &pd[idx]; -} - bool init_mplane(ru_session_list_t *ru_session_list) { paramdef_t fhip[] = ORAN_GLOBALPARAMS_DESC; diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index 31c754738d..149f492e6a 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -102,6 +102,7 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status) AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMap == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id); for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) { + LOG_D(HW, "cb pRbMap->nPrbElm %d\n", pRbMap->nPrbElm); for (uint32_t idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++ ) { struct xran_prb_elm *pRbElm = &pRbMap->prbMap[idxElm]; pRbElm->nSecDesc[sym_id] = 0; // number of section descriptors per symbol; M-plane info @@ -173,6 +174,9 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot) struct xran_fh_init *fh_init = get_xran_fh_init(); struct xran_fh_config *fh_cfg = get_xran_fh_config(0); nr_prach_info_t prach_info = get_prach_info(0); + + int prach_start_sym = prach_info.start_symbol; + int prach_end_sym = prach_info.N_dur + prach_start_sym; struct xran_ru_config *ru_conf = &fh_cfg->ru_conf; int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology; int slots_per_subframe = 1 << fh_cfg->frame_conf.nNumerology; @@ -190,7 +194,7 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot) LOG_W(HW, "we get rach data from ru, but it is not scheduled %d.%d\n", frame, slot); return -1; } - for (sym_idx = 0; sym_idx < prach_info.N_dur; sym_idx++) { + for (sym_idx = prach_start_sym; sym_idx < prach_end_sym; sym_idx++) { for (int aa = 0; aa < ru->nb_rx; aa++) { int16_t *dst, *src; int idx = 0; @@ -200,7 +204,7 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot) src = (int16_t *)bufs->prachdstdecomp[aa % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers[sym_idx].pData; /* convert Network order to host order */ if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_NONE) { - if (sym_idx == 0) { + if (sym_idx == prach_start_sym) { for (idx = 0; idx < 139 * 2; idx++) { dst[idx] = ((int16_t)ntohs(src[idx + g_kbar])); } @@ -233,7 +237,7 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot) AssertFatal(1 == 0, "BFP decompression not supported on this architecture"); #endif // note: this is hardwired for 139 point PRACH sequence, kbar=2 - if (sym_idx == 0) // + if (sym_idx == prach_start_sym) for (idx = 0; idx < (139 * 2); idx++) dst[idx] = local_dst[idx + g_kbar]; else @@ -262,6 +266,28 @@ static bool is_tdd_ul_symbol(const struct xran_frame_config *frame_conf, int slo return frame_conf->sSlotConfig[slot_in_period].nSymbolType[sym_idx] == 1 /* UL */; } +/** @brief Check if symbol in slot is DL. + * + * @param frame_conf xran frame configuration + * @param slot the current (absolute) slot (number) + * @param sym_idx the current symbol index */ +static bool is_tdd_dl_symbol(const struct xran_frame_config *frame_conf, int slot, int sym_idx) +{ + /* in FDD, every symbol is also UL */ + if (frame_conf->nFrameDuplexType == XRAN_FDD) + return true; + int tdd_period = frame_conf->nTddPeriod; + int slot_in_period = slot % tdd_period; + /* check if symbol is UL */ + return frame_conf->sSlotConfig[slot_in_period].nSymbolType[sym_idx] == 0 /* DL */; +} + +/** @brief Check if current slot is guard/mixed */ +static bool is_tdd_guard_slot(const struct xran_frame_config *frame_conf, int slot) +{ + return (is_tdd_dl_symbol(frame_conf, slot, 0) && is_tdd_ul_symbol(frame_conf, slot, XRAN_NUM_OF_SYMBOL_PER_SLOT - 1)); +} + /** @brief Check if current slot is DL or guard/mixed without UL (i.e., current * slot is not UL). */ static bool is_tdd_dl_guard_slot(const struct xran_frame_config *frame_conf, int slot) @@ -338,7 +364,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) const struct xran_fh_init *fh_init = get_xran_fh_init(); int nPRBs = fh_cfg->nULRBs; - int fftsize = 1 << fh_cfg->ru_conf.fftSize; + int fftsize = 1 << fh_cfg->nULFftSize; int slot_offset_rxdata = 3 & (*slot); uint32_t slot_size = 4 * 14 * fftsize; @@ -496,7 +522,7 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) const struct xran_fh_init *fh_init = get_xran_fh_init(); const struct xran_fh_config *fh_cfg = get_xran_fh_config(0); int nPRBs = fh_cfg->nDLRBs; - int fftsize = 1 << fh_cfg->ru_conf.fftSize; + int fftsize = 1 << fh_cfg->nDLFftSize; int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports; int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports; @@ -675,3 +701,470 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) } return (0); } + +/** @details Read PRACH and PUSCH data from xran buffers. If + * I/Q compression (bitwidth < 16 bits) is configured, deccompresses the data + * before writing. Prints ON TIME counters every 128 frames. + * + * Function is blocking and waits for next frame/slot combination. It is unblocked + * by oai_xran_fh_rx_callback(). It writes the current slot into parameters + * frame/slot. */ +int xran_fh_rx_read_slot_BySymbol(ru_info_t *ru, int *frame, int *slot) +{ + void *ptr = NULL; + int32_t *pos = NULL; + int idx = 0; + + static int64_t old_rx_counter[XRAN_PORTS_NUM] = {0}; + static int64_t old_tx_counter[XRAN_PORTS_NUM] = {0}; + struct xran_common_counters x_counters[XRAN_PORTS_NUM]; + static int outcnt = 0; + #ifndef USE_POLLING + // pull next even from oran_sync_fifo + notifiedFIFO_elt_t *res = pullNotifiedFIFO(&oran_sync_fifo); + + notifiedFIFO_elt_t *f; + while ((f = pollNotifiedFIFO(&oran_sync_fifo)) != NULL) { + oran_sync_info_t *old_info = NotifiedFifoData(res); + oran_sync_info_t *new_info = NotifiedFifoData(f); + LOG_E(HW, "Detected double sync message %d.%d => %d.%d\n", old_info->f, old_info->sl, new_info->f, new_info->sl); + delNotifiedFIFO_elt(res); + res = f; + } + + oran_sync_info_t *info = NotifiedFifoData(res); + + *slot = info->sl; + *frame = info->f; + delNotifiedFIFO_elt(res); +#else + *slot = oran_sync_info.sl; + *frame = oran_sync_info.f; + uint32_t tti_in = oran_sync_info.tti; + + static int last_slot = -1; + LOG_D(HW, "oran slot %d, last_slot %d\n", *slot, last_slot); + int cnt = 0; + // while (*slot == last_slot) { + while (tti_in == oran_sync_info.tti) { + //*slot = oran_sync_info.sl; + cnt++; + } + LOG_D(HW, "cnt %d, Reading %d.%d\n", cnt, *frame, *slot); + last_slot = *slot; +#endif + // return(0); + + struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology; + + int tti = slots_per_frame * (*frame) + (*slot); + + read_prach_data(ru, *frame, *slot); + + const struct xran_fh_init *fh_init = get_xran_fh_init(); + int nPRBs = fh_cfg->nULRBs; + int fftsize = 1 << fh_cfg->ru_conf.fftSize; + + int slot_offset_rxdata = 3 & (*slot); + uint32_t slot_size = 4 * 14 * fftsize; + uint8_t *rx_data = (uint8_t *)ru->rxdataF[0]; + uint8_t *start_ptr = NULL; + int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports; + for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet. + for (uint8_t ant_id = 0; ant_id < ru->nb_rx; ant_id++) { + rx_data = (uint8_t *)ru->rxdataF[ant_id]; + start_ptr = rx_data + (slot_size * slot_offset_rxdata); + const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_rx_per_ru)->frame_conf; + // skip processing this slot is TX (no RX in this slot) + if (!is_tdd_ul_guard_slot(frame_conf, *slot)) + continue; + bool sym_start_found = false; + int32_t sym_start = 0; + // This loop would better be more inner to avoid confusion and maybe also errors. + for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) { + /* the callback is for mixed and UL slots. In mixed, we have to + * skip DL and guard symbols. */ + if (!is_tdd_ul_symbol(frame_conf, *slot, sym_idx)) + continue; + if (!sym_start_found) { + sym_start = sym_idx; + sym_start_found = true; + } + + uint8_t *pData; + oran_buf_list_t *bufs = get_xran_buffers(ant_id / nb_rx_per_ru); + uint8_t *pPrbMapData = bufs->dstcp[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; + struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData; + + struct xran_prb_map *pRbMap = pPrbMap; + for (int idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) { + struct xran_prb_elm *pRbElm = &pRbMap->prbMap[idxElm]; +#ifdef E_RELEASE + struct xran_section_desc *p_sec_desc = pRbElm->p_sec_desc[sym_idx][0]; + uint32_t one_rb_size = + (((pRbElm->iqWidth == 0) || (pRbElm->iqWidth == 16)) ? (N_SC_PER_PRB * 2 * 2) : (3 * pRbElm->iqWidth + 1)); + if (fh_init->mtu < pRbElm->nRBSize * one_rb_size) + pData = bufs->dst[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN] + .pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT] + .pData; + else + pData = p_sec_desc->pData; +#elif defined F_RELEASE + struct xran_section_desc *p_sec_desc = &pRbElm->sec_desc[sym_idx][0]; + pData = p_sec_desc->pData; +#endif + ptr = pData; + pos = (int32_t *)(start_ptr + (4 * sym_idx * fftsize)); + if (ptr == NULL || pos == NULL) + continue; + + uint8_t *src = (uint8_t *)ptr; + + LOG_D(HW, "rx pRbMap->nPrbElm %d\n", pRbMap->nPrbElm); + // For Liteon FR2 with RunSlotPrbMapBySymbolEnable xran_prb_map will have xran_prb_elm prbMap[14], each idxElm matches to sym_idx. + u_int8_t section_id_tmp = pPrbMap->nPrbElm < XRAN_NUM_OF_SYMBOL_PER_SLOT ? sym_idx - sym_start: sym_idx; + if (section_id_tmp != pRbElm->nSectId) { + LOG_D(HW, + "rx prbMap[%d] : PRBstart %d nPRBs %d nSectId %d != sym_idx %d:%d\n", + idxElm, + pRbMap->prbMap[idxElm].nRBStart, + pRbMap->prbMap[idxElm].nRBSize, + pRbMap->prbMap[idxElm].nSectId, sym_idx, section_id_tmp + ); + continue; + } + LOG_D(HW, + "rx prbMap[%d] : PRBstart %d:%d nPRBs %d:%d nSectId %d sym_idx %d:%d\n", + idxElm, + pRbMap->prbMap[idxElm].nRBStart, pRbMap->prbMap[idxElm].UP_nRBStart, + pRbMap->prbMap[idxElm].nRBSize, pRbMap->prbMap[idxElm].UP_nRBSize, + pRbMap->prbMap[idxElm].nSectId, sym_idx, section_id_tmp + ); + + int pos_len = 0; + int neg_len = 0; + int num_prbu = p_sec_desc->num_prbu; + int start_prbu = p_sec_desc->start_prbu; + if (start_prbu < (nPRBs >> 1)) // there are PRBs left of DC + neg_len = min((nPRBs * 6) - (start_prbu * 12), num_prbu * N_SC_PER_PRB); + pos_len = (num_prbu * N_SC_PER_PRB) - neg_len; + + src = pData; + // Calculation of the pointer for the section in the buffer. + // positive half + uint8_t *dst1 = (uint8_t *)(pos + (neg_len == 0 ? ((start_prbu * N_SC_PER_PRB) - (nPRBs * 6)) : 0)); + // negative half + uint8_t *dst2 = (uint8_t *)(pos + (start_prbu * N_SC_PER_PRB) + fftsize - (nPRBs * 6)); + int32_t local_dst[num_prbu * N_SC_PER_PRB] __attribute__((aligned(64))); + if (pRbElm->compMethod == XRAN_COMPMETHOD_NONE) { + // NOTE: gcc 11 knows how to generate AVX2 for this! + for (idx = 0; idx < num_prbu * N_SC_PER_PRB * 2; idx++) + ((int16_t *)local_dst)[idx] = ((int16_t)ntohs(((uint16_t *)src)[idx])) >> 2; + memcpy((void *)dst2, (void *)local_dst, neg_len * 4); + memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4); + } else if (pRbElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) { +#if defined(__i386__) || defined(__x86_64__) + struct xranlib_decompress_request bfp_decom_req = {}; + struct xranlib_decompress_response bfp_decom_rsp = {}; + + int16_t payload_len = (3 * pRbElm->iqWidth + 1) * num_prbu; + + bfp_decom_req.data_in = (int8_t *)src; + bfp_decom_req.numRBs = num_prbu; + bfp_decom_req.len = payload_len; + bfp_decom_req.compMethod = pRbElm->compMethod; + bfp_decom_req.iqWidth = pRbElm->iqWidth; + + bfp_decom_rsp.data_out = (int16_t *)local_dst; + bfp_decom_rsp.len = 0; + + xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp); +#elif defined(__arm__) || defined(__aarch64__) + armral_bfp_decompression(pRbElm->iqWidth, num_prbu, (int8_t *)src, (int16_t *)local_dst); +#else + AssertFatal(1 == 0, "BFP compression not supported on this architecture"); +#endif + memcpy((void *)dst2, (void *)local_dst, neg_len * 4); + memcpy((void *)dst1, (void *)&local_dst[neg_len], pos_len * 4); + outcnt++; + } else { + printf("pRbElm->compMethod == %d is not supported\n", pRbElm->compMethod); + exit(-1); + } + } + } // sym_ind + } // ant_ind + } // vv_inf + if ((*frame & 0x7f) == 0 && *slot == 0 && xran_get_common_counters(gxran_handle, &x_counters[0]) == XRAN_STATUS_SUCCESS) { + for (int o_xu_id = 0; o_xu_id < fh_init->xran_ports; o_xu_id++) { + LOG_I(HW, + "[%s%d][rx %7ld pps %7ld kbps %7ld][tx %7ld pps %7ld kbps %7ld][Total Msgs_Rcvd %ld]\n", + "o-du ", + o_xu_id, + x_counters[o_xu_id].rx_counter, + x_counters[o_xu_id].rx_counter - old_rx_counter[o_xu_id], + x_counters[o_xu_id].rx_bytes_per_sec * 8 / 1000L, + x_counters[o_xu_id].tx_counter, + x_counters[o_xu_id].tx_counter - old_tx_counter[o_xu_id], + x_counters[o_xu_id].tx_bytes_per_sec * 8 / 1000L, + x_counters[o_xu_id].Total_msgs_rcvd); + for (int rxant = 0; rxant < ru->nb_rx / fh_init->xran_ports; rxant++) + LOG_I(HW, + "[%s%d][pusch%d %7ld prach%d %7ld]\n", + "o_du", + o_xu_id, + rxant, + x_counters[o_xu_id].rx_pusch_packets[rxant], + rxant, + x_counters[o_xu_id].rx_prach_packets[rxant]); + if (x_counters[o_xu_id].rx_counter > old_rx_counter[o_xu_id]) + old_rx_counter[o_xu_id] = x_counters[o_xu_id].rx_counter; + if (x_counters[o_xu_id].tx_counter > old_tx_counter[o_xu_id]) + old_tx_counter[o_xu_id] = x_counters[o_xu_id].tx_counter; + } + } + return (0); +} + +/** @details Write PDSCH IQ-data from OAI txdataF_BF buffer to xran buffers. If + * I/Q compression (bitwidth < 16 bits) is configured, compresses the data + * before writing. */ +int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t timestamp) +{ + int tti = /*frame*SUBFRAMES_PER_SYSTEMFRAME*SLOTNUM_PER_SUBFRAME+*/ 20 * frame + + slot; // commented out temporarily to check that compilation of oran 5g is working. + + void *ptr = NULL; + int32_t *pos = NULL; + int idx = 0; + + const struct xran_fh_init *fh_init = get_xran_fh_init(); + const struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + int nPRBs = fh_cfg->nDLRBs; + int fftsize = 1 << fh_cfg->ru_conf.fftSize; + int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports; + int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports; + + // Handle CP UL packet here instead of at xran_fh_rx_read_slot() as oran_fh_if4p5_south_in() lags behind + // oran_fh_if4p5_south_out() (which is invoked at the right time slot) by 4 slots. + // Need to use --continuous-tx so that this routine will be triggered in RX slot. + for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet. + for (uint8_t ant_id = 0; ant_id < ru->nb_rx; ant_id++) { + const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_rx_per_ru)->frame_conf; + // skip processing this slot is TX (no RX in this slot) + if (!is_tdd_ul_guard_slot(frame_conf, slot)) { + continue; + } + bool sym_start_found = false; + int32_t sym_start = 0; + // This loop would better be more inner to avoid confusion and maybe also errors. + for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) { + /* the callback is for mixed and UL slots. In mixed, we have to + * skip DL and guard symbols. */ + if (!is_tdd_ul_symbol(frame_conf, slot, sym_idx)) { + continue; + } + if (!sym_start_found) { + sym_start = sym_idx; + sym_start_found = true; + } + + oran_buf_list_t *bufs = get_xran_buffers(ant_id / nb_rx_per_ru); + uint8_t *pPrbMapData = bufs->dstcp[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; + struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData; + + struct xran_prb_elm *pRbElm = &pPrbMap->prbMap[0]; + + struct xran_prb_map *pRbMap = pPrbMap; + uint32_t idxElm = 0; + + LOG_D(HW, "tx0 pRbMap->nPrbElm %d\n", pRbMap->nPrbElm); + for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) { + LOG_D(HW, "prbMap[%d] : PRBstart %d nPRBs %d\n", idxElm, pRbMap->prbMap[idxElm].nRBStart, pRbMap->prbMap[idxElm].nRBSize); + pRbElm = &pRbMap->prbMap[idxElm]; + // For Liteon FR2 with RunSlotPrbMapBySymbolEnable xran_prb_map will have xran_prb_elm prbMap[14], each idxElm matches to sym_idx. + u_int8_t section_id_tmp = pPrbMap->nPrbElm < XRAN_NUM_OF_SYMBOL_PER_SLOT ? sym_idx - sym_start: sym_idx; + if (section_id_tmp != pRbElm->nSectId) { + LOG_D(HW, + "tx0 prbMap[%d] : PRBstart %d:%d nPRBs %d:%d nSectId %d != sym_idx %d:%d\n", + idxElm, + pRbMap->prbMap[idxElm].nRBStart, pRbMap->prbMap[idxElm].UP_nRBStart, + pRbMap->prbMap[idxElm].nRBSize, pRbMap->prbMap[idxElm].UP_nRBSize, + pRbMap->prbMap[idxElm].nSectId, sym_idx, section_id_tmp + ); + continue; + } + LOG_D(HW, + "tx0 prbMap[%d] : PRBstart %d:%d nPRBs %d:%d nSectId %d sym_idx %d:%d\n", + idxElm, + pRbMap->prbMap[idxElm].nRBStart, pRbMap->prbMap[idxElm].UP_nRBStart, + pRbMap->prbMap[idxElm].nRBSize, pRbMap->prbMap[idxElm].UP_nRBSize, + pRbMap->prbMap[idxElm].nSectId, sym_idx, section_id_tmp + ); + + // ant_id / no of antenna per beam gives the beam_nb + pRbElm->nBeamIndex = ru->beam_id[ant_id / (ru->nb_rx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT + sym_idx]; + // In phy-f-1.0/fhi_lib/lib/api/xran_pkt_cp.h, beamId:15 is of 15bit. -1 set extension bit ef:1 to 1 mistakenly. + if (pRbElm->nBeamIndex == -1) + pRbElm->nBeamIndex = 0; + } + } + } + } + + for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet. + for (uint8_t ant_id = 0; ant_id < ru->nb_tx; ant_id++) { + oran_buf_list_t *bufs = get_xran_buffers(ant_id / nb_tx_per_ru); + const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_tx_per_ru)->frame_conf; + // skip processing this slot is TX (no TX in this slot) + if (!is_tdd_dl_guard_slot(frame_conf, slot)) { + continue; + } + + // Set nPrbElm if beam_id = -1 for all downlink symbols + bool beam_used = false; + uint8_t *pPrbMapData = bufs->srccp[ant_id % nb_tx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; + struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData; + struct xran_prb_map *pRbMap = pPrbMap; + int32_t dl_sym_end = 0; + for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) { + if (is_tdd_dl_symbol(frame_conf, slot, sym_idx)) { + if (ru->beam_id[ant_id / (ru->nb_tx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT+ sym_idx] != -1) + beam_used |= true; + } + else { + dl_sym_end = sym_idx; + break; + } + } + if (is_tdd_guard_slot(frame_conf, slot)) + pRbMap->nPrbElm = dl_sym_end; + else + pRbMap->nPrbElm = XRAN_NUM_OF_SYMBOL_PER_SLOT; + if (!beam_used) { + pRbMap->nPrbElm = 0; + continue; + } + + // This loop would better be more inner to avoid confusion and maybe also errors. + for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) { + /* the callback is for mixed and UL slots. In mixed, we have to + * skip UL and guard symbols. */ + if (is_tdd_ul_symbol(frame_conf, slot, sym_idx)) { + continue; + } + uint8_t *pData = + bufs->src[ant_id % nb_tx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT].pData; + uint8_t *pPrbMapData = bufs->srccp[ant_id % nb_tx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; + struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData; + ptr = pData; + pos = &ru->txdataF_BF[ant_id][sym_idx * fftsize]; + + uint8_t *u8dptr; + struct xran_prb_map *pRbMap = pPrbMap; + int32_t sym_id = sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT; + if (ptr && pos) { + uint32_t idxElm = 0; + u8dptr = (uint8_t *)ptr; + int16_t payload_len = 0; + + uint8_t *dst = (uint8_t *)u8dptr; + + struct xran_prb_elm *p_prbMapElm = &pRbMap->prbMap[idxElm]; + LOG_D(HW, "tx1 pRbMap->nPrbElm %d\n", pRbMap->nPrbElm); + for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) { + // For Liteon FR2 with RunSlotPrbMapBySymbolEnable xran_prb_map will have xran_prb_elm prbMap[14], each idxElm matches to sym_idx. + struct xran_section_desc *p_sec_desc = NULL; + p_prbMapElm = &pRbMap->prbMap[idxElm]; + if (sym_idx != p_prbMapElm->nSectId) + continue; + // ant_id / no of antenna per beam gives the beam_nb + p_prbMapElm->nBeamIndex = ru->beam_id[ant_id / (ru->nb_tx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT+ sym_idx]; + // In phy-f-1.0/fhi_lib/lib/api/xran_pkt_cp.h, beamId:15 is of 15bit. -1 set extension bit ef:1 to 1 mistakenly. + if (p_prbMapElm->nBeamIndex == -1) + p_prbMapElm->nBeamIndex = 0; + + // assumes one fragment per symbol +#ifdef E_RELEASE + p_sec_desc = p_prbMapElm->p_sec_desc[sym_id][0]; +#elif F_RELEASE + p_sec_desc = &p_prbMapElm->sec_desc[sym_id][0]; +#endif + + dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod); + + if (p_sec_desc == NULL) { + printf("p_sec_desc == NULL\n"); + exit(-1); + } + uint16_t *dst16 = (uint16_t *)dst; + + int pos_len = 0; + int neg_len = 0; + + if (p_prbMapElm->UP_nRBStart < (nPRBs >> 1)) // there are PRBs left of DC + neg_len = min((nPRBs * 6) - (p_prbMapElm->UP_nRBStart * 12), p_prbMapElm->UP_nRBSize * N_SC_PER_PRB); + pos_len = (p_prbMapElm->UP_nRBSize * N_SC_PER_PRB) - neg_len; + // Calculation of the pointer for the section in the buffer. + // start of positive frequency component + uint16_t *src1 = (uint16_t *)&pos[(neg_len == 0) ? ((p_prbMapElm->UP_nRBStart * N_SC_PER_PRB) - (nPRBs * 6)) : 0]; + // start of negative frequency component + uint16_t *src2 = (uint16_t *)&pos[(p_prbMapElm->UP_nRBStart * N_SC_PER_PRB) + fftsize - (nPRBs * 6)]; + + uint32_t local_src[p_prbMapElm->UP_nRBSize * N_SC_PER_PRB] __attribute__((aligned(64))); + memcpy((void *)local_src, (void *)src2, neg_len * 4); + memcpy((void *)&local_src[neg_len], (void *)src1, pos_len * 4); + if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) { + payload_len = p_prbMapElm->UP_nRBSize * N_SC_PER_PRB * 4L; + /* convert to Network order */ + // NOTE: ggc 11 knows how to generate AVX2 for this! + for (idx = 0; idx < (pos_len + neg_len) * 2; idx++) + ((uint16_t *)dst16)[idx] = htons(((uint16_t *)local_src)[idx]); + } else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) { + payload_len = (3 * p_prbMapElm->iqWidth + 1) * p_prbMapElm->UP_nRBSize; + +#if defined(__i386__) || defined(__x86_64__) + struct xranlib_compress_request bfp_com_req = {}; + struct xranlib_compress_response bfp_com_rsp = {}; + + bfp_com_req.data_in = (int16_t *)local_src; + bfp_com_req.numRBs = p_prbMapElm->UP_nRBSize; + bfp_com_req.len = payload_len; + bfp_com_req.compMethod = p_prbMapElm->compMethod; + bfp_com_req.iqWidth = p_prbMapElm->iqWidth; + + bfp_com_rsp.data_out = (int8_t *)dst; + bfp_com_rsp.len = 0; + + xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp); +#elif defined(__arm__) || defined(__aarch64__) + armral_bfp_compression(p_prbMapElm->iqWidth, p_prbMapElm->UP_nRBSize, (int16_t *)local_src, (int8_t *)dst); +#else + AssertFatal(1 == 0, "BFP compression not supported on this architecture"); +#endif + + } else { + printf("p_prbMapElm->compMethod == %d is not supported\n", p_prbMapElm->compMethod); + exit(-1); + } + + p_sec_desc->iq_buffer_offset = RTE_PTR_DIFF(dst, u8dptr); + p_sec_desc->iq_buffer_len = payload_len; + + dst += payload_len; + dst = xran_add_hdr_offset(dst, p_prbMapElm->compMethod); + } + + // The tti should be updated as it increased. + pRbMap->tti_id = tti; + + } else { + printf("ptr ==NULL\n"); + exit(-1); // fails here?? + } + } + } + } + return (0); +} diff --git a/radio/fhi_72/oran-config.c b/radio/fhi_72/oran-config.c index 684d44e7cf..00c13bc64d 100644 --- a/radio/fhi_72/oran-config.c +++ b/radio/fhi_72/oran-config.c @@ -431,23 +431,17 @@ void print_fh_config(const struct xran_fh_config *fh_config) #ifdef F_RELEASE printf("\ RunSlotPrbMapBySymbolEnable %d\n\ + LiteOnIgnoreUPSectionIdEnable %d\n\ dssEnable %d\n\ dssPeriod %d\n\ technology[XRAN_MAX_DSS_PERIODICITY] (not filled as DSS disabled)\n", fh_config->RunSlotPrbMapBySymbolEnable, + fh_config->LiteOnIgnoreUPSectionIdEnable, fh_config->dssEnable, fh_config->dssPeriod); #endif } -static const paramdef_t *gpd(const paramdef_t *pd, int num, const char *name) -{ - /* the config module does not know const-correctness... */ - int idx = config_paramidx_fromname((paramdef_t *)pd, num, (char *)name); - DevAssert(idx >= 0); - return &pd[idx]; -} - static uint64_t get_u64_mask(const paramdef_t *pd) { DevAssert(pd != NULL); @@ -762,7 +756,8 @@ static bool set_fh_prach_config(void *mplane_api, const uint32_t max_num_ant, const paramdef_t *prachp, int nprach, - struct xran_prach_config *prach_config) + struct xran_prach_config *prach_config, + bool liteon_prach_eAxC_offset) { const split7_config_t *s7cfg = &oai0->split7; @@ -799,7 +794,10 @@ static bool set_fh_prach_config(void *mplane_api, prach_config->eAxC_offset = xran_mplane->prach_offset; #else uint8_t offset = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_EAXC_OFFSET)->u8ptr; - prach_config->eAxC_offset = (offset != 0) ? offset : max_num_ant; + if (liteon_prach_eAxC_offset) + prach_config->eAxC_offset = offset; + else + prach_config->eAxC_offset = (offset != 0) ? offset : max_num_ant; #endif g_kbar = *gpd(prachp, nprach, ORAN_PRACH_CONFIG_KBAR)->uptr; @@ -921,8 +919,8 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c fh_config->neAxc = RTE_MAX(oai0->tx_num_channels / num_rus, oai0->rx_num_channels / num_rus); // number of eAxc supported on one CC = max(PDSCH, PUSCH) fh_config->neAxcUl = 0; // number of eAxc supported on one CC for UL direction = PUSCH; used only if XRAN_CATEGORY_B fh_config->nAntElmTRx = 0; // number of antenna elements for TX and RX = SRS; used only if XRAN_CATEGORY_B - fh_config->nDLFftSize = 0; // DL FFT size; not used in xran - fh_config->nULFftSize = 0; // UL FFT size; not used in xran + fh_config->nDLFftSize = oai0->split7.fftSize; // DL FFT size; not used in xran + fh_config->nULFftSize = oai0->split7.fftSize; // UL FFT size; not used in xran fh_config->nDLRBs = oai0->num_rb_dl; // DL PRB; used in oaioran.c/oran-init.c; not used in xran, neither in E nor in F release fh_config->nULRBs = oai0->num_rb_dl; // UL PRB; used in oaioran.c/oran-init.c; in xran E release not used so the patch fixes it, but in xran F release this value is properly used fh_config->nDLAbsFrePointA = 0; // Abs Freq Point A of the Carrier Center Frequency for in KHz Value; not used in xran @@ -945,9 +943,14 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c fh_config->enableCP = 1; // enable C-plane fh_config->prachEnable = 1; // enable PRACH fh_config->srsEnable = 0; // enable SRS; used only if XRAN_CATEGORY_B + // For LiteOn E release, no need to take care of prach eAxC_offset. xran lib is hacked to handle it. + bool liteon_prach_eAxC_offset = false; #ifdef F_RELEASE fh_config->srsEnableCp = 0; // enable SRS CP; used only if XRAN_CATEGORY_B fh_config->SrsDelaySym = 0; // number of SRS delay symbols; used only if XRAN_CATEGORY_B + fh_config->RunSlotPrbMapBySymbolEnable = *gpd(fhp, nfh, ORAN_CONFIG_RunSlotPrbMapBySymbol)->uptr; // enable RunSlotPrbMapBySymbol + fh_config->LiteOnIgnoreUPSectionIdEnable = *gpd(fhp, nfh, ORAN_CONFIG_LiteOnIgnoreUPSectionId)->uptr; // enable LiteOnIgnoreUPSectionId + liteon_prach_eAxC_offset = fh_config->LiteOnIgnoreUPSectionIdEnable; #endif fh_config->puschMaskEnable = 0; // enable PUSCH mask; only used if id = O_RU fh_config->puschMaskSlot = 0; // specific which slot PUSCH channel masked; only used if id = O_RU @@ -959,14 +962,14 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c fh_config->GPS_Alpha = 0; // refers to alpha as defined in section 9.7.2 of ORAN spec. this value should be alpha*(1/1.2288ns), range 0 - 1e7 (ns); offset_nsec = (pConf->GPS_Beta - offset_sec * 100) * 1e7 + pConf->GPS_Alpha fh_config->GPS_Beta = 0; // beta value as defined in section 9.7.2 of ORAN spec. range -32767 ~ +32767; offset_sec = pConf->GPS_Beta / 100 - if (!set_fh_prach_config(mplane_api, oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf)) + if (!set_fh_prach_config(mplane_api, oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf, liteon_prach_eAxC_offset)) return false; /* SRS only used if XRAN_CATEGORY_B Note: srs_config->eAxC_offset >= prach_config->eAxC_offset + PRACH */ // fh_config->srs_conf = {0}; if (!set_fh_frame_config(oai0, &fh_config->frame_conf)) return false; - if (!set_fh_ru_config(mplane_api, rup, oai0->split7.fftSize, nru, xran_cat, &fh_config->ru_conf)) + if (!set_fh_ru_config(mplane_api, rup, oai0->split7.prach_fftSize, nru, xran_cat, &fh_config->ru_conf)) return false; fh_config->bbdev_enc = NULL; // call back to poll BBDev encoder @@ -991,8 +994,6 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c fh_config->max_sections_per_symbol = 0; // not used in xran #ifdef F_RELEASE - fh_config->RunSlotPrbMapBySymbolEnable = 0; // enable PRB mapping by symbol with multisection - fh_config->dssEnable = 0; // enable DSS (extension-9) fh_config->dssPeriod = 0; // DSS pattern period for LTE/NR // fh_config->technology[XRAN_MAX_DSS_PERIODICITY] // technology array represents slot is LTE(0)/NR(1); used only if DSS enabled diff --git a/radio/fhi_72/oran-init.c b/radio/fhi_72/oran-init.c index 516c2795fe..9707084a2f 100644 --- a/radio/fhi_72/oran-init.c +++ b/radio/fhi_72/oran-init.c @@ -333,6 +333,7 @@ static void oran_allocate_buffers(void *handle, struct xran_prb_map dlPmMixed = {0}; struct xran_prb_map ulPmMixed = {0}; uint32_t idx = 0; + if (fh_config->frame_conf.nFrameDuplexType == XRAN_TDD) { oran_mixed_slot_t info = get_mixed_slot_info(&fh_config->frame_conf); dlPmMixed = get_xran_prb_map(fh_config, XRAN_DIR_DL, 0, info.num_dlsym); @@ -357,8 +358,16 @@ static void oran_allocate_buffers(void *handle, #ifdef E_RELEASE uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (xran_max_sections_per_slot - 1); #elif defined F_RELEASE - uint32_t numPrbElm = xran_get_num_prb_elm(&dlPm, mtu); - uint32_t size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm); + uint32_t size_of_prb_map; + if (fh_config->RunSlotPrbMapBySymbolEnable) { + // For Liteon FR2 with RunSlotPrbMapBySymbolEnable, xran_prb_map will have xran_prb_elm prbMap[14] + size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (XRAN_NUM_OF_SYMBOL_PER_SLOT); + } + else { + // For non-Liteon w/o RunSlotPrbMapBySymbolEnable, xran_prb_map will have xran_prb_elm prbMap[1] + uint32_t numPrbElm = xran_get_num_prb_elm(&dlPm, mtu); + size_of_prb_map = sizeof(struct xran_prb_map) + sizeof(struct xran_prb_elm) * (numPrbElm); + } #endif // PDSCH diff --git a/radio/fhi_72/oran-params.h b/radio/fhi_72/oran-params.h index baeefbc68d..9f12418909 100644 --- a/radio/fhi_72/oran-params.h +++ b/radio/fhi_72/oran-params.h @@ -95,6 +95,8 @@ #define CONFIG_STRING_ORAN_FH "fh_config" +#define ORAN_CONFIG_RunSlotPrbMapBySymbol "RunSlotPrbMapBySymbol" +#define ORAN_CONFIG_LiteOnIgnoreUPSectionId "LiteOnIgnoreUPSectionId" #define ORAN_FH_CONFIG_T1A_CP_DL "T1a_cp_dl" #define ORAN_FH_CONFIG_T1A_CP_UL "T1a_cp_ul" #define ORAN_FH_CONFIG_T1A_UP "T1a_up" @@ -104,10 +106,12 @@ // clang-format off #define ORAN_FH_DESC { \ - {ORAN_FH_CONFIG_T1A_CP_DL, "T1a_cp_dl" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ - {ORAN_FH_CONFIG_T1A_CP_UL, "T1a_cp_ul" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ - {ORAN_FH_CONFIG_T1A_UP, "T1a_up" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ - {ORAN_FH_CONFIG_TA4, "Ta4" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {ORAN_CONFIG_RunSlotPrbMapBySymbol, "RunSlotPrbMapBySymbol\n", PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ + {ORAN_CONFIG_LiteOnIgnoreUPSectionId, "Liteon Ignore Section Id\n", PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ + {ORAN_FH_CONFIG_T1A_CP_DL, "T1a_cp_dl" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {ORAN_FH_CONFIG_T1A_CP_UL, "T1a_cp_ul" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {ORAN_FH_CONFIG_T1A_UP, "T1a_up" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {ORAN_FH_CONFIG_TA4, "Ta4" ORAN_FH_HLP_CPLT, PARAMFLAG_MANDATORY, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ } // clang-format on diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index 679936d9c9..9b97b58390 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -228,7 +228,12 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot) int f, sl; LOG_D(HW, "Read rxdataF %p,%p\n", ru_info.rxdataF[0], ru_info.rxdataF[1]); start_meas(&ru->rx_fhaul); - int ret = xran_fh_rx_read_slot(&ru_info, &f, &sl); + struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + int ret = 0; + if (fh_cfg->RunSlotPrbMapBySymbolEnable) + ret = xran_fh_rx_read_slot_BySymbol(&ru_info, &f, &sl); + else + ret = xran_fh_rx_read_slot(&ru_info, &f, &sl); stop_meas(&ru->rx_fhaul); LOG_D(HW, "Read %d.%d rxdataF %p,%p\n", f, sl, ru_info.rxdataF[0], ru_info.rxdataF[1]); if (ret != 0) { @@ -283,7 +288,12 @@ void oran_fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) // printf("south_out:\tframe=%d\tslot=%d\ttimestamp=%ld\n",frame,slot,timestamp); - int ret = xran_fh_tx_send_slot(&ru_info, frame, slot, timestamp); + struct xran_fh_config *fh_cfg = get_xran_fh_config(0); + int ret = 0; + if (fh_cfg->RunSlotPrbMapBySymbolEnable) + ret = xran_fh_tx_send_slot_BySymbol(&ru_info, frame, slot, timestamp); + else + ret = xran_fh_tx_send_slot(&ru_info, frame, slot, timestamp); if (ret != 0) { printf("ORAN: ORAN_fh_if4p5_south_out ERROR in TX function \n"); } diff --git a/radio/fhi_72/oran_isolate.h b/radio/fhi_72/oran_isolate.h index 6ec011a24b..bb3f17d42b 100644 --- a/radio/fhi_72/oran_isolate.h +++ b/radio/fhi_72/oran_isolate.h @@ -60,7 +60,9 @@ typedef struct ru_info_s { * @param frame output of the frame which has been read. * @param slot output of the slot which has been read. */ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot); +int xran_fh_rx_read_slot_BySymbol(ru_info_t *ru, int *frame, int *slot); /** @brief Writes TX data (PDSCH) of given slot. */ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp); +int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t timestamp); #endif /* _ORAN_ISOLATE_H_ */ diff --git a/radio/rfsimulator/CMakeLists.txt b/radio/rfsimulator/CMakeLists.txt index ad4d92f108..2b04f7dd89 100644 --- a/radio/rfsimulator/CMakeLists.txt +++ b/radio/rfsimulator/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(rfsimulator MODULE - simulator.c + simulator.cpp apply_channelmod.c ../../openair1/PHY/TOOLS/signal_energy.c ) diff --git a/radio/rfsimulator/README.md b/radio/rfsimulator/README.md index 40688b755a..298c7ecfda 100644 --- a/radio/rfsimulator/README.md +++ b/radio/rfsimulator/README.md @@ -209,3 +209,55 @@ to reduce the amount of transported samples: A possible, unimplemented optimization would be to compress samples. You can further [tune your machine](../../doc/tuning_and_security.md) + +# Beam simulation + +RFsimulator supports beam domain simulation. + +## Configuration + +Several new CLI parameters were added + +* `--rfsimulator.enable_beams` : enable beam domain simulation. Should match on server and all clients. +* `--rfsimulator.beam_gains ` : define a matrix of additional pathloss values (in dB) +to simulate the effect of different beam combinations in the RF simulator. You provide a comma-separated +list of numbers, which forms the first row of a square matrix. The rest of the matrix is filled by projecting +these values onto the diagonals, making it symmetric. + + Example list: `0,-2,-3` + Resulting matrix: + ``` + [[0,-2,-3], + [-2,0,-2], + [-3,-2,0]] + ``` + + The beam gain matrix will be used during beam combining. RX beam selects the row and TX beam selects column. + Using the example above, if gNB is receiving in beam 1 and the UE is transmitting in beam 1, an additional + 2 dB pathloss will be applied on top of the pathloss from the channel model (if present). + +* `--rfsimulator.beam_map ` : where `` is a `uint64_t` value where each bit is an enabled TX/RX beam. + For gNB: Initial beam_map, i.e. which beams gNB transmits/receives before calling beam APIs. + For UE: Beam position in beam space in the simulation. The UE is not expected to use the beam APIs for now. +* `--rfsimulator.beam_ids ` : where `` is a comma separated list. Same as above but added for convenience. + +## Runtime commands + +### Moving the UE in beam space + +Use telnet command `rfsimu setbeams ` or `rfsimu setbeamids `. They correspond to the CLI parameters described +above and work the same way. + +### Modifying the gNB beam + +It is possible to test the beam domain simulation without implementing the beam APIs. The same telnet command can be used +to modify the tx/rx beam of the gNB. The gNB does not need to be beam-aware and use the new APIs. + +## Programming guide + +RFsimulator is attempting to simulate hardware device operation, but there are differences. Like with real hardware, +it is expected that you provide the configured beams in `set_beams` function ahead of sample reception. This is due +to the fact that a hardware device will buffer received samples before the driver requests them. + +For rfsimulator, as long as the call to `set_beams` with timestamp `n` is done before `trx_read` which is expected +to return sample `n` the beam switch command will apply to the received samples. diff --git a/radio/rfsimulator/apply_channelmod.c b/radio/rfsimulator/apply_channelmod.c index a976c63264..d1d1042451 100644 --- a/radio/rfsimulator/apply_channelmod.c +++ b/radio/rfsimulator/apply_channelmod.c @@ -1,26 +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 -* -* 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 -*/ - + * 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 @@ -28,36 +27,17 @@ #include "openair2/LAYER2/NR_MAC_gNB/mac_config.h" #include "rfsimulator.h" -/* - Legacy study: - The parameters are: - gain&loss (decay, signal power, ...) - either a fixed gain in dB, a target power in dBm or ACG (automatic control gain) to a target average - => don't redo the AGC, as it was used in UE case, that must have a AGC inside the UE - will be better to handle the "set_gain()" called by UE to apply it's gain (enable test of UE power loop) - lin_amp = pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas); - a lot of operations in legacy, grouped in one simulation signal decay: txgain*decay*rxgain - - multi_path (auto convolution, ISI, ...) - either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes - legacy: we regenerate each sub frame in UL, and each frame only in DL -*/ -void rxAddInput(const c16_t *input_sig, - cf_t *after_channel_sig, - int rxAnt, - channel_desc_t *channelDesc, - int nbSamples, - uint64_t TS, - uint32_t CirSize, - bool add_noise) +void update_channel_model(channel_desc_t *channelDesc, uint64_t TS) { static uint64_t last_TS = 0; - - if ((channelDesc->sat_height > 0) && (channelDesc->enable_dynamic_delay || channelDesc->enable_dynamic_Doppler)) { // model for transparent satellite on circular orbit + if ((channelDesc->sat_height > 0) + && (channelDesc->enable_dynamic_delay + || channelDesc->enable_dynamic_Doppler)) { // model for transparent satellite on circular orbit /* assumptions: - The Earth is spherical, the ground station is static, and that the Earth does not rotate. - An access or link is possible from the satellite to the ground station at all times. - - The ground station is located at the North Pole (positive Zaxis), and the satellite starts from the initial elevation angle 0° in the second quadrant of the YZplane. + - The ground station is located at the North Pole (positive Zaxis), and the satellite starts from the initial elevation angle + 0° in the second quadrant of the YZplane. - Satellite moves in the clockwise direction in its circular orbit. */ const double radius_earth = 6377900; // m @@ -78,14 +58,14 @@ void rxAddInput(const c16_t *input_sig, const double pos_sat_z = radius_sat * cos(w_sat * t); const double vel_sat_x = 0; - const double vel_sat_y = w_sat * radius_sat * cos(w_sat * t); + const double vel_sat_y = w_sat * radius_sat * cos(w_sat * t); const double vel_sat_z = -w_sat * radius_sat * sin(w_sat * t); const double pos_ue_x = 0; const double pos_ue_y = 0; const double pos_ue_z = radius_earth; - const double c = 299792458; // m/s + const double c = (double) SPEED_OF_LIGHT; if (channelDesc->is_uplink) { const double dir_ue_sat_x = pos_sat_x - pos_ue_x; @@ -99,21 +79,54 @@ void rxAddInput(const c16_t *input_sig, double vel_sat_gnb = 0; double acc_sat_gnb = 0; if (channelDesc->modelid == SAT_LEO_TRANS) { - const double acc_sat_x = 0; - const double acc_sat_y = -w_sat * w_sat * radius_sat * sin(w_sat * t); - const double acc_sat_z = -w_sat * w_sat * radius_sat * cos(w_sat * t); + const double t5 = t + 5; + const double t10 = t + 10; const double pos_gnb_x = 0; const double pos_gnb_y = 0; const double pos_gnb_z = radius_earth; + const double pos_sat_x5 = 0; + const double pos_sat_y5 = radius_sat * sin(w_sat * t5); + const double pos_sat_z5 = radius_sat * cos(w_sat * t5); + + const double pos_sat_x10 = 0; + const double pos_sat_y10 = radius_sat * sin(w_sat * t10); + const double pos_sat_z10 = radius_sat * cos(w_sat * t10); + const double dir_sat_gnb_x = pos_gnb_x - pos_sat_x; const double dir_sat_gnb_y = pos_gnb_y - pos_sat_y; const double dir_sat_gnb_z = pos_gnb_z - pos_sat_z; + const double dir_sat_gnb_x5 = pos_gnb_x - pos_sat_x5; + const double dir_sat_gnb_y5 = pos_gnb_y - pos_sat_y5; + const double dir_sat_gnb_z5 = pos_gnb_z - pos_sat_z5; + + const double dir_sat_gnb_x10 = pos_gnb_x - pos_sat_x10; + const double dir_sat_gnb_y10 = pos_gnb_y - pos_sat_y10; + const double dir_sat_gnb_z10 = pos_gnb_z - pos_sat_z10; + dist_sat_gnb = sqrt(dir_sat_gnb_x * dir_sat_gnb_x + dir_sat_gnb_y * dir_sat_gnb_y + dir_sat_gnb_z * dir_sat_gnb_z); - vel_sat_gnb = (vel_sat_x * dir_sat_gnb_x + vel_sat_y * dir_sat_gnb_y + vel_sat_z * dir_sat_gnb_z) / dist_sat_gnb; - acc_sat_gnb = (acc_sat_x * dir_sat_gnb_x + acc_sat_y * dir_sat_gnb_y + acc_sat_z * dir_sat_gnb_z) / dist_sat_gnb; + const double dist_sat_gnb5 = sqrt(dir_sat_gnb_x5 * dir_sat_gnb_x5 + dir_sat_gnb_y5 * dir_sat_gnb_y5 + dir_sat_gnb_z5 * dir_sat_gnb_z5); + const double dist_sat_gnb10 = sqrt(dir_sat_gnb_x10 * dir_sat_gnb_x10 + dir_sat_gnb_y10 * dir_sat_gnb_y10 + dir_sat_gnb_z10 * dir_sat_gnb_z10); + + // calculate vel_sat_gnb and acc_sat_gnb, so the delay is correct for epoch_time, epoch_time + 5 seconds and epoch_time + 10 seconds + // + // dist_sat_gnb = dist_sat_gnb + 0 * vel_sat_gnb + 0 * acc_sat_gnb; + // dist_sat_gnb5 = dist_sat_gnb + 5 * vel_sat_gnb + 25 * acc_sat_gnb; + // dist_sat_gnb10 = dist_sat_gnb + 10 * vel_sat_gnb + 100 * acc_sat_gnb; + // + // vel_sat_gnb = (dist_sat_gnb5 - dist_sat_gnb) / 5 - 5 * acc_sat_gnb; + // acc_sat_gnb = (dist_sat_gnb10 - dist_sat_gnb) / 100 - vel_sat_gnb / 10; + // + // vel_sat_gnb = (dist_sat_gnb5 - dist_sat_gnb) / 5 - 5 * ((dist_sat_gnb10 - dist_sat_gnb) / 100 - vel_sat_gnb / 10); + + vel_sat_gnb = 2 * (dist_sat_gnb5 - dist_sat_gnb) / 5 - (dist_sat_gnb10 - dist_sat_gnb) / 10; + acc_sat_gnb = (dist_sat_gnb10 - dist_sat_gnb) / 50 - (dist_sat_gnb5 - dist_sat_gnb) / 25; + + // in the moment when the satellite disappears behind the horizon acc_sat_gnb might become negative, what is invalid + if (acc_sat_gnb < 0) + acc_sat_gnb = 0; } const double prop_delay = (dist_ue_sat + dist_sat_gnb) / c; @@ -124,11 +137,19 @@ void rxAddInput(const c16_t *input_sig, if (channelDesc->enable_dynamic_Doppler) channelDesc->Doppler_phase_inc = 2 * M_PI * f_Doppler_shift_ue_sat / channelDesc->sampling_rate; - if(TS - last_TS >= channelDesc->sampling_rate) { + if (TS - last_TS >= channelDesc->sampling_rate) { last_TS = TS; - LOG_I(HW, "Satellite orbit: time %f s, Position = (%f, %f, %f), Velocity = (%f, %f, %f)\n", t, pos_sat_x, pos_sat_y, pos_sat_z, vel_sat_x, vel_sat_y, vel_sat_z); + LOG_I(HW, + "Satellite orbit: time %f s, Position = (%f, %f, %f), Velocity = (%f, %f, %f)\n", + t, + pos_sat_x, + pos_sat_y, + pos_sat_z, + vel_sat_x, + vel_sat_y, + vel_sat_z); LOG_I(HW, "Uplink delay %f ms, Doppler shift UE->SAT %f kHz\n", prop_delay * 1000, f_Doppler_shift_ue_sat / 1000); - LOG_I(HW, "Satellite velocity towards gNB: %f m/s, acceleration towards gNB: %f m/s²\n", vel_sat_gnb, acc_sat_gnb); + LOG_I(HW, "Satellite velocity towards gNB: %f m/s, acceleration towards gNB: %f m/s²\n", -vel_sat_gnb, acc_sat_gnb); } const int samples_per_subframe = channelDesc->sampling_rate / 1000; @@ -138,7 +159,7 @@ void rxAddInput(const c16_t *input_sig, .sfn = (abs_subframe / 10 + 1) % 1024, .subframe = 0, .delay = 2 * dist_sat_gnb / (c * 4.072e-9), - .drift = 2 * -vel_sat_gnb / (c * 0.2e-9), + .drift = 2 * vel_sat_gnb / (c * 0.2e-9), .accel = 2 * acc_sat_gnb / (c * 0.2e-10), .position.X = pos_sat_x / 1.3, .position.Y = pos_sat_y / 1.3, @@ -183,48 +204,70 @@ void rxAddInput(const c16_t *input_sig, if (channelDesc->enable_dynamic_Doppler) channelDesc->Doppler_phase_inc = 2 * M_PI * f_Doppler_shift_sat_ue / channelDesc->sampling_rate; - if(TS - last_TS >= channelDesc->sampling_rate) { + if (TS - last_TS >= channelDesc->sampling_rate) { last_TS = TS; - LOG_I(HW, "Satellite orbit: time %f s, Position = (%f, %f, %f), Velocity = (%f, %f, %f)\n", t, pos_sat_x, pos_sat_y, pos_sat_z, vel_sat_x, vel_sat_y, vel_sat_z); + LOG_I(HW, + "Satellite orbit: time %f s, Position = (%f, %f, %f), Velocity = (%f, %f, %f)\n", + t, + pos_sat_x, + pos_sat_y, + pos_sat_z, + vel_sat_x, + vel_sat_y, + vel_sat_z); LOG_I(HW, "Downlink delay %f ms, Doppler shift SAT->UE %f kHz\n", prop_delay * 1000, f_Doppler_shift_sat_ue / 1000); } } } +} +/* + Legacy study: + The parameters are: + gain&loss (decay, signal power, ...) + either a fixed gain in dB, a target power in dBm or ACG (automatic control gain) to a target average + => don't redo the AGC, as it was used in UE case, that must have a AGC inside the UE + will be better to handle the "set_gain()" called by UE to apply it's gain (enable test of UE power loop) + lin_amp = pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas); + a lot of operations in legacy, grouped in one simulation signal decay: txgain*decay*rxgain + + multi_path (auto convolution, ISI, ...) + either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes + legacy: we regenerate each sub frame in UL, and each frame only in DL +*/ +void rxAddInput(c16_t **input_sig, + cf_t *after_channel_sig, + int rxAnt, + channel_desc_t *channelDesc, + int nbSamples, + uint64_t TS) +{ // channelDesc->path_loss_dB should contain the total path gain // so, in actual RF: tx gain + path loss + rx gain (+antenna gain, ...) // UE and NB gain control to be added // Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...) - const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0); + const double pathLossLinear = pow(10, channelDesc->path_loss_dB / 20.0); // Energy in one sample to calibrate input noise // the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1) - const double noise_per_sample = add_noise ? pow(10,channelDesc->noise_power_dB/10.0) * 256 : 0; - const uint64_t dd = channelDesc->channel_offset; - const int nbTx=channelDesc->nb_tx; + const double noise_per_sample = pow(10, channelDesc->noise_power_dB / 10.0) * 256; + const int nbTx = channelDesc->nb_tx; double Doppler_phase_cur = channelDesc->Doppler_phase_cur[rxAnt]; Doppler_phase_cur -= 2 * M_PI * round(Doppler_phase_cur / (2 * M_PI)); - for (int i=0; ich[rxAnt+(txAnt*channelDesc->nb_rx)]; + for (int txAnt = 0; txAnt < nbTx; txAnt++) { + const struct complexd *channelModel = channelDesc->ch[rxAnt + (txAnt * channelDesc->nb_rx)]; - //const struct complex *channelModelEnd=channelModel+channelDesc->channel_length; - for (int l = 0; l<(int)channelDesc->channel_length; l++) { - // let's assume TS+i >= l - // fixme: the rfsimulator current structure is interleaved antennas - // this has been designed to not have to wait a full block transmission - // but it is not very usefull - // it would be better to split out each antenna in a separate flow - // that will allow to mix ru antennas freely - // (X + cirSize) % cirSize to ensure that index is positive - const int idx = ((TS + i - l - dd) * nbTx + txAnt + CirSize) % CirSize; - const struct complex16 tx16 = input_sig[idx]; + // const struct complex *channelModelEnd=channelModel+channelDesc->channel_length; + for (int l = 0; l < (int)channelDesc->channel_length; l++) { + const int idx = i - l + channelDesc->channel_length - 1; + const struct complex16 tx16 = input_sig[txAnt][idx]; rx_tmp.r += tx16.r * channelModel[l].r - tx16.i * channelModel[l].i; rx_tmp.i += tx16.i * channelModel[l].r + tx16.r * channelModel[l].i; - } //l + } // l } if (channelDesc->Doppler_phase_inc != 0.0) { @@ -246,12 +289,11 @@ void rxAddInput(const c16_t *input_sig, channelDesc->Doppler_phase_cur[rxAnt] = Doppler_phase_cur; - if ( (TS*nbTx)%CirSize+nbSamples <= CirSize ) - // Cast to a wrong type for compatibility ! - LOG_D(HW,"Input power %f, output power: %f, channel path loss %f, noise coeff: %f \n", - 10*log10((double)signal_energy((int32_t *)&input_sig[(TS*nbTx)%CirSize], nbSamples)), - 10*log10((double)signal_energy((int32_t *)after_channel_sig, nbSamples)), - channelDesc->path_loss_dB, - 10*log10(noise_per_sample)); + // Cast to a wrong type for compatibility ! + LOG_D(HW, + "Input power %f, output power: %f, channel path loss %f, noise coeff: %f \n", + 10 * log10((double)signal_energy((int32_t *)&input_sig[0], nbSamples)), + 10 * log10((double)signal_energy((int32_t *)after_channel_sig, nbSamples)), + channelDesc->path_loss_dB, + 10 * log10(noise_per_sample)); } - diff --git a/radio/rfsimulator/rfsimulator.h b/radio/rfsimulator/rfsimulator.h index 11a57193ca..802a2a2e34 100644 --- a/radio/rfsimulator/rfsimulator.h +++ b/radio/rfsimulator/rfsimulator.h @@ -1,37 +1,34 @@ /* -* 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 -*/ + * 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 __RFSIMULATOR_H -#define __RFSIMULATOR_H +#define __RFSIMULATOR_H #include -void rxAddInput( const c16_t *input_sig, - cf_t *after_channel_sig, - int rxAnt, - channel_desc_t *channelDesc, - int nbSamples, - uint64_t TS, - uint32_t CirSize, - bool apply_noise - ); - +void rxAddInput(c16_t **input_sig, + cf_t *after_channel_sig, + int rxAnt, + channel_desc_t *channelDesc, + int nbSamples, + uint64_t TS); +void update_channel_model(channel_desc_t *channelDesc, uint64_t TS); #endif diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.cpp similarity index 51% rename from radio/rfsimulator/simulator.c rename to radio/rfsimulator/simulator.cpp index 94234a755f..ef6be135e6 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.cpp @@ -27,6 +27,10 @@ * When the opposite side switch from passive reading to active R+Write, the synchro is not fully deterministic */ +#include "PHY/TOOLS/tools_defs.h" +#include "PHY/defs_common.h" +#include "utils.h" +#include #include #include #include @@ -42,34 +46,34 @@ #include #include -#include #include #include #include "common_lib.h" #define CHANNELMOD_DYNAMICLOAD +extern "C" { +#include #include #include "rfsimulator.h" +extern int get_currentchannels_type(const char *buf, + int debug, + webdatadef_t *tdata, + telnet_printfunc_t prnt); // in random_channel.c +} +#include +#include +#include +#include +#include +#include #define PORT 4043 // default TCP port for this simulator -// -// CirSize defines the number of samples inquired for a read cycle -// It is bounded by a slot read capability (which depends on bandwidth and numerology) -// up to multiple slots read to allow I/Q buffering of the I/Q TCP stream -// -// As a rule of thumb: -// -it can't be less than the number of samples for a slot -// -it can range up to multiple slots -// -// The default value is chosen for 10ms buffering which makes 23040*20 = 460800 samples -// The previous value is kept below in comment it was computed for 100ms 1x 20MHz -// #define CirSize 6144000 // 100ms SiSo 20MHz LTE -#define minCirSize 460800 // 10ms SiSo 40Mhz 3/4 sampling NR78 FR1 #define sampleToByte(a, b) ((a) * (b) * sizeof(sample_t)) #define byteToSample(a, b) ((a) / (sizeof(sample_t) * (b))) #define GENERATE_CHANNEL 10 // each frame (or slot?) in DL #define MAX_FD_RFSIMU 250 #define SEND_BUFF_SIZE 100000000 // Socket buffer size +#define MAX_BEAMS 64 // Simulator role typedef enum { SIMU_ROLE_SERVER = 1, SIMU_ROLE_CLIENT } simuRole; @@ -78,37 +82,46 @@ typedef enum { SIMU_ROLE_SERVER = 1, SIMU_ROLE_CLIENT } simuRole; #define RFSIMU_SECTION "rfsimulator" #define RFSIMU_OPTIONS_PARAMNAME "options" +#define RFSIMU_BEAM_GAINS "beam_gains" +#define RFSIMU_BEAM_IDS "beam_ids" #define RFSIM_CONFIG_HELP_OPTIONS \ " list of comma separated options to enable rf simulator functionalities. Available options: \n" \ " chanmod: enable channel modelisation\n" \ " saviq: enable saving written iqs to a file\n" -// clang-format off -/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* configuration parameters for the rfsimulator device */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define simOpt PARAMFLAG_NOFREE | PARAMFLAG_CMDLINE_NOPREFIXENABLED +#define simBool PARAMFLAG_BOOL | PARAMFLAG_NOFREE | PARAMFLAG_CMDLINE_NOPREFIXENABLED +// clang-format off +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* configuration parameters for the rfsimulator device */ +/* optname helpstr paramflags XXXptr defXXXval */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define RFSIMULATOR_PARAMS_DESC { \ - {"serveraddr", "\n", simOpt, .strptr=&rfsimulator->ip, .defstrval="127.0.0.1", TYPE_STRING, 0 },\ - {"serverport", "\n", simOpt, .u16ptr = &(rfsimulator->port), .defuintval = PORT, TYPE_UINT16, 0}, \ - {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, .strlistptr = NULL, .defstrlistval = NULL, TYPE_STRINGLIST, 0}, \ - {"IQfile", "\n",simOpt, .strptr=&saveF, .defstrval="/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ - {"modelname", "\n", simOpt, .strptr = &modelname, .defstrval = "AWGN", TYPE_STRING, 0}, \ - {"ploss", "\n", simOpt, .dblptr = &(rfsimulator->chan_pathloss), .defdblval = 0, TYPE_DOUBLE, 0}, \ - {"forgetfact", "\n", simOpt, .dblptr=&(rfsimulator->chan_forgetfact),.defdblval=0, TYPE_DOUBLE, 0 },\ - {"offset", "\n", simOpt, .u64ptr = &(rfsimulator->chan_offset), .defint64val = 0, TYPE_UINT64, 0}, \ - {"prop_delay", "\n", simOpt, .dblptr=&(rfsimulator->prop_delay_ms), .defdblval=0.0, TYPE_DOUBLE, 0 },\ - {"wait_timeout", "\n", simOpt, .iptr=&(rfsimulator->wait_timeout), .defintval=1, TYPE_INT, 0 },\ - }; + STRINGPARAM("serveraddr", "\n", simOpt, &rfsimulator->ip, "127.0.0.1"), \ + UINT16PARAM("serverport", "\n", simOpt, &rfsimulator->port, PORT), \ + STRLISTPARAM(RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, simOpt, NULL, NULL), \ + STRINGPARAM("IQfile", "\n", simOpt, &saveF, "/tmp/rfsimulator.iqs"),\ + STRINGPARAM("modelname", "\n", simOpt, &modelname, "AWGN"), \ + DOUBLEPARAM("ploss", "\n", simOpt, &rfsimulator->chan_pathloss, 0), \ + DOUBLEPARAM("forgetfact", "\n", simOpt, &rfsimulator->chan_forgetfact, 0), \ + UINT64PARAM("offset", "\n", simOpt, &rfsimulator->chan_offset, 0L), \ + DOUBLEPARAM("prop_delay", "\n", simOpt, &(rfsimulator->prop_delay_ms), 0.0), \ + INTPARAM("wait_timeout", "\n", simOpt, &rfsimulator->wait_timeout, 1), \ + BOOLPARAM("enable_beams", "\n", simBool,&(beam_ctrl->enable_beams), 0), \ + INTPARAM("num_concurrent_beams", "\n", simOpt, &beam_ctrl->num_concurrent_beams, 1), \ + UINT64PARAM("beam_map", "\n", simOpt, &beam_map, 1), \ + STRINGPARAM(RFSIMU_BEAM_IDS, "\n", simOpt, NULL, NULL), \ + STRINGPARAM(RFSIMU_BEAM_GAINS, "\n", simOpt, NULL, NULL), \ +}; // clang-format on static void getset_currentchannels_type(char *buf, int debug, webdatadef_t *tdata, telnet_printfunc_t prnt); -extern int get_currentchannels_type(char *buf, int debug, webdatadef_t *tdata, telnet_printfunc_t prnt); // in random_channel.c static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg); static int rfsimu_setdistance_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg); static int rfsimu_getdistance_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg); static int rfsimu_vtime_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg); +static int rfsimu_set_beam(char *buff, int debug, telnet_printfunc_t prnt, void *arg); +static int rfsimu_set_beamids(char *buff, int debug, telnet_printfunc_t prnt, void *arg); // clang-format off static telnetshell_cmddef_t rfsimu_cmdarray[] = { {"show models", "", (cmdfunc_t)rfsimu_setchanmod_cmd, {(webfunc_t)getset_currentchannels_type}, TELNETSRV_CMDFLAG_WEBSRVONLY | TELNETSRV_CMDFLAG_GETWEBTBLDATA, NULL}, @@ -116,28 +129,56 @@ static telnetshell_cmddef_t rfsimu_cmdarray[] = { {"setdistance", " ", (cmdfunc_t)rfsimu_setdistance_cmd, {NULL}, TELNETSRV_CMDFLAG_PUSHINTPOOLQ | TELNETSRV_CMDFLAG_NEEDPARAM }, {"getdistance", "", (cmdfunc_t)rfsimu_getdistance_cmd, {NULL}, TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, {"vtime", "", (cmdfunc_t)rfsimu_vtime_cmd, {NULL}, TELNETSRV_CMDFLAG_PUSHINTPOOLQ | TELNETSRV_CMDFLAG_AUTOUPDATE}, + {"setbeam", "beam_map", (cmdfunc_t)rfsimu_set_beam, {NULL}, TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, + {"setbeamids", "beam_id1,beam_id2,...", (cmdfunc_t)rfsimu_set_beamids, {NULL}, TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, {"", "", NULL}, }; // clang-format on static telnetshell_cmddef_t *setmodel_cmddef = &(rfsimu_cmdarray[1]); static telnetshell_vardef_t rfsimu_vardef[] = {{"", 0, 0, NULL}}; -static uint64_t CirSize = minCirSize; typedef c16_t sample_t; // 2*16 bits complex number +typedef struct beam_switch_command_t { + std::vector beams; + openair0_timestamp timestamp; +} beam_switch_command_t; + +typedef struct { + std::vector beams; + std::queue cmd_queue; + std::mutex mutex; +} beam_state_t; + +typedef struct { + samplesBlockHeader_t header; + char payload[1]; +} rfsim_packet_t; + typedef struct buffer_s { int conn_sock; openair0_timestamp lastReceivedTS; bool headerMode; bool trashingPacket; samplesBlockHeader_t th; + uint nbAnt; char *transferPtr; uint64_t remainToTransfer; - char *circularBufEnd; - sample_t *circularBuf; channel_desc_t *channel_model; + rfsim_packet_t *packet_ptr; + size_t payload_sz; + size_t remainToTransferBeam; + std::queue received_packets; } buffer_t; +typedef struct { + int enable_beams; + int num_concurrent_beams; + std::vector> beam_gains; + beam_state_t tx; + beam_state_t rx; +} rfsim_beam_ctrl_t; + typedef struct { int listen_sock, epollfd; pthread_mutex_t Sockmutex; @@ -163,8 +204,122 @@ typedef struct { poll_telnetcmdq_func_t poll_telnetcmdq; int wait_timeout; double prop_delay_ms; + rfsim_beam_ctrl_t *beam_ctrl; } rfsimulator_state_t; +/** + * @brief Get the current beam map for a given timestamp and number of samples. + * + * This function retrieves the beam map from the beam state, considering any queued beam switch commands. + * + * @param beam_state Pointer to the beam_state_t structure containing the current beam map and command queue. + * @param timestamp The timestamp for which the beam map is requested. + * @param nsamps The number of samples to process. + * @param nsamps_out output pointer to receive the number of samples until the next beam switch. + * @return The beam map (uint64_t) valid for the given timestamp. + */ +static std::vector get_beams(beam_state_t *beam_state, openair0_timestamp timestamp, uint32_t nsamps, uint32_t *nsamps_out) +{ + std::lock_guard lock(beam_state->mutex); + std::vector current_beams = beam_state->beams; + uint32_t samples_to_next_switch = nsamps; + + // Find the latest beam_switch_command_t with timestamp <= requested timestamp + if (!beam_state->cmd_queue.empty()) { + // Copy queue to avoid modifying original + std::queue queue_copy = beam_state->cmd_queue; + while (!queue_copy.empty()) { + const beam_switch_command_t &cmd = queue_copy.front(); + if (cmd.timestamp <= timestamp) { + current_beams = cmd.beams; + queue_copy.pop(); + } else { + samples_to_next_switch = (cmd.timestamp > timestamp) ? (cmd.timestamp - timestamp) : nsamps; + break; + } + } + } + + // Clamp samples_to_next_switch to nsamps + if (samples_to_next_switch > nsamps) + samples_to_next_switch = nsamps; + + *nsamps_out = samples_to_next_switch; + + return current_beams; +} + + +static std::vector beam_map_to_beams(uint64_t beam_map) +{ + int num_beams = __builtin_popcountll(beam_map); + AssertFatal(num_beams > 0, "Needs at least one beam\n"); + std::vector beam_ids; + for (int i = 0; i < MAX_BEAMS; i++) { + if (beam_map & (1ULL << i)) { + beam_ids.push_back(i); + } + } + return beam_ids; +} + +static uint64_t beams_to_beam_map(const std::vector &beam_ids) +{ + uint64_t beam_map = 0; + for (size_t i = 0; i < beam_ids.size(); i++) { + beam_map |= (1ULL << beam_ids[i]); + } + return beam_map; +} + + +/** + * @brief Clears outdated beam switch commands from the queue and updates the current beam map. + * + * This function processes the beam switch command queue in the given beam_state_t. + * For each command with a timestamp less than or equal to the provided timestamp, + * it updates the current beam_map and removes the command from the queue. + * The queue is left unchanged for commands with timestamps greater than the provided timestamp. + * + * @param beam_state Pointer to the beam_state_t structure containing the command queue and current beam map. + * @param timestamp The timestamp up to which commands should be processed and removed. + */ +static void clear_beam_queue(beam_state_t *beam_state, openair0_timestamp timestamp) +{ + std::lock_guard lock(beam_state->mutex); + while (!beam_state->cmd_queue.empty()) { + if (beam_state->cmd_queue.front().timestamp <= timestamp) { + beam_state->beams = beam_state->cmd_queue.front().beams; + beam_state->cmd_queue.pop(); + } else { + break; + } + } +} + +/** + * @brief Clears old packets from the received_packets queue based on a threshold timestamp. + * + * This function iterates through the received_packets queue and removes packets whose + * timestamp plus size is less than or equal to the provided threshold_timestamp. + * It frees the memory allocated for each removed packet. + * + * @param received_packets Reference to the queue of rfsim_packet_t pointers representing received packets. + * @param threshold_timestamp The timestamp threshold used to determine which packets to remove. + */ +static void clear_old_packets(std::queue &received_packets, uint64_t threshold_timestamp) +{ + while (!received_packets.empty()) { + rfsim_packet_t *pkt = received_packets.front(); + if (pkt->header.timestamp + pkt->header.size <= threshold_timestamp) { + free(pkt); + received_packets.pop(); + } else { + break; + } + } +} + static bool flushInput(rfsimulator_state_t *t, int timeout, bool first_time); static buffer_t *allocCirBuf(rfsimulator_state_t *bridge, int sock) @@ -172,18 +327,13 @@ static buffer_t *allocCirBuf(rfsimulator_state_t *bridge, int sock) uint64_t buff_index = bridge->next_buf++ % MAX_FD_RFSIMU; buffer_t *ptr = &bridge->buf[buff_index]; bridge->nb_cnx++; - ptr->circularBuf = calloc(1, sampleToByte(CirSize, 1)); - if (ptr->circularBuf == NULL) { - LOG_E(HW, "malloc(%lu) failed\n", sampleToByte(CirSize, 1)); - return NULL; - } - ptr->circularBufEnd = ((char *)ptr->circularBuf) + sampleToByte(CirSize, 1); ptr->conn_sock = sock; ptr->lastReceivedTS = 0; ptr->headerMode = true; ptr->trashingPacket = true; ptr->transferPtr = (char *)&ptr->th; ptr->remainToTransfer = sizeof(samplesBlockHeader_t); + ptr->received_packets = std::queue(); int sendbuff = SEND_BUFF_SIZE; if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) != 0) { LOG_E(HW, "setsockopt(SO_SNDBUF) failed\n"); @@ -199,20 +349,6 @@ static buffer_t *allocCirBuf(rfsimulator_state_t *bridge, int sock) if (bridge->channelmod > 0) { // create channel simulation model for this mode reception - static bool init_done = false; - - if (!init_done) { - uint64_t rand; - FILE *h = fopen("/dev/random", "r"); - - if (1 != fread(&rand, sizeof(rand), 1, h)) - LOG_W(HW, "Can't read /dev/random\n"); - - fclose(h); - randominit(rand); - tableNor(rand); - init_done = true; - } char modelname[30]; snprintf(modelname, sizeofArray(modelname), @@ -222,7 +358,7 @@ static buffer_t *allocCirBuf(rfsimulator_state_t *bridge, int sock) ptr->channel_model = find_channel_desc_fromname(modelname); // path_loss in dB if (!ptr->channel_model) { // Use legacy method to find channel model - this will use the same channel model for all clients - char *legacy_model_name = (bridge->role == SIMU_ROLE_SERVER) ? "rfsimu_channel_ue0" : "rfsimu_channel_enB0"; + const char *legacy_model_name = (bridge->role == SIMU_ROLE_SERVER) ? "rfsimu_channel_ue0" : "rfsimu_channel_enB0"; ptr->channel_model = find_channel_desc_fromname(legacy_model_name); if (!ptr->channel_model) { LOG_E(HW, "Channel model %s/%s not found, check config file\n", modelname, legacy_model_name); @@ -244,11 +380,11 @@ static void removeCirBuf(rfsimulator_state_t *bridge, buffer_t *buf) LOG_E(HW, "epoll_ctl(EPOLL_CTL_DEL) failed\n"); } close(buf->conn_sock); - free(buf->circularBuf); // Fixme: no free_channel_desc_scm(bridge->buf[sock].channel_model) implemented // a lot of mem leaks // free(bridge->buf[sock].channel_model); - memset(buf, 0, sizeof(buffer_t)); + clear_old_packets(buf->received_packets, INT64_MAX); + *buf = buffer_t{}; buf->conn_sock = -1; bridge->nb_cnx--; } @@ -264,10 +400,7 @@ static void socketError(rfsimulator_state_t *bridge, buffer_t *buf) } } -enum blocking_t { - notBlocking, - blocking -}; +enum blocking_t { notBlocking, blocking }; static int setblocking(int sock, enum blocking_t active) { @@ -290,13 +423,14 @@ static int setblocking(int sock, enum blocking_t active) return 0; } -static void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { +static void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) +{ if (t->saveIQfile != -1) { if (write(t->saveIQfile, _buf, count) != count) LOG_E(HW, "write() in save iq file failed (%d)\n", errno); } - char *buf = _buf; + char *buf = static_cast(_buf); ssize_t l; while (count) { @@ -326,9 +460,70 @@ static void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) } } -static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { +static float get_rx_gain_db(rfsimulator_state_t *rfsimulator, uint rx_beam, uint tx_beam) +{ + if (!rfsimulator->beam_ctrl->enable_beams) { + return 0; + } + AssertFatal(rx_beam < rfsimulator->beam_ctrl->beam_gains.size() && tx_beam < rfsimulator->beam_ctrl->beam_gains[rx_beam].size(), + "Beam gain for this combination was not provided rx_beam %d tx_beam %d\n", + rx_beam, + tx_beam); + return rfsimulator->beam_ctrl->beam_gains[rx_beam][tx_beam]; +} + +static int rfsimulator_set_beams(openair0_device *device, uint64_t beam_map, openair0_timestamp timestamp) +{ + rfsimulator_state_t *s = static_cast(device->priv); + rfsim_beam_ctrl_t *beam_ctrl = s->beam_ctrl; + std::lock_guard lock_tx(beam_ctrl->tx.mutex); + std::lock_guard lock_rx(beam_ctrl->rx.mutex); + beam_switch_command_t command = {.beams = beam_map_to_beams(beam_map), .timestamp = timestamp}; + beam_ctrl->rx.cmd_queue.emplace(command); + beam_ctrl->tx.cmd_queue.emplace(command); + return 0; +} + +static int rfsimulator_set_beams_vector(openair0_device *device, int* beams, int num_beams, openair0_timestamp timestamp) +{ + rfsimulator_state_t *s = static_cast(device->priv); + rfsim_beam_ctrl_t *beam_ctrl = s->beam_ctrl; + std::lock_guard lock_tx(beam_ctrl->tx.mutex); + std::lock_guard lock_rx(beam_ctrl->rx.mutex); + beam_switch_command_t command = {.beams = std::vector(beams, beams + num_beams), .timestamp = timestamp}; + beam_ctrl->rx.cmd_queue.emplace(command); + beam_ctrl->tx.cmd_queue.emplace(command); + return 0; +} + +static void process_gains(char *str, rfsim_beam_ctrl_t *beam_ctrl) +{ + int num_gains = 0; + float gain_array[MAX_BEAMS]; + std::stringstream ss(str); + std::string token; + while (std::getline(ss, token, ',') && num_gains < MAX_BEAMS) { + gain_array[num_gains++] = std::stof(token); + } + + if (num_gains != 0) { + for (int i = 0; i < num_gains; i++) { + std::vector beam_gains; + for (int j = 0; j < num_gains; j++) { + int diag = abs(i - j); + beam_gains.push_back(gain_array[diag]); + } + beam_ctrl->beam_gains.push_back(beam_gains); + } + } +} + +static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) +{ char *saveF = NULL; char *modelname = NULL; + rfsim_beam_ctrl_t *beam_ctrl = rfsimulator->beam_ctrl; + uint64_t beam_map = 1; paramdef_t rfsimu_params[] = RFSIMULATOR_PARAMS_DESC; int p = config_paramidx_fromname(rfsimu_params, sizeofArray(rfsimu_params), RFSIMU_OPTIONS_PARAMNAME); int ret = config_get(config_get_if(), rfsimu_params, sizeofArray(rfsimu_params), RFSIMU_SECTION); @@ -350,7 +545,11 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { break; } else if (strcmp(rfsimu_params[p].strlistptr[i], "chanmod") == 0) { init_channelmod(); - load_channellist(rfsimulator->tx_num_channels, rfsimulator->rx_num_channels, rfsimulator->sample_rate, rfsimulator->rx_freq, rfsimulator->tx_bw); + load_channellist(rfsimulator->tx_num_channels, + rfsimulator->rx_num_channels, + rfsimulator->sample_rate, + rfsimulator->rx_freq, + rfsimulator->tx_bw); rfsimulator->channelmod = true; } else { fprintf(stderr, "unknown rfsimulator option: %s\n", rfsimu_params[p].strlistptr[i]); @@ -358,14 +557,68 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { } } - if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 || - strncasecmp(rfsimulator->ip,"server",3) == 0 ) + int beam_gains_param_index = config_paramidx_fromname(rfsimu_params, sizeofArray(rfsimu_params), RFSIMU_BEAM_GAINS); + if (rfsimu_params[beam_gains_param_index].strptr) { + process_gains(*rfsimu_params[beam_gains_param_index].strptr, beam_ctrl); + } + + std::vector initial_beams = beam_map_to_beams(beam_map); + beam_ctrl->rx.beams = initial_beams; + beam_ctrl->tx.beams = initial_beams; + + int beam_ids_param_index = config_paramidx_fromname(rfsimu_params, sizeofArray(rfsimu_params), RFSIMU_BEAM_IDS); + if (rfsimu_params[beam_ids_param_index].strptr) { + std::vector beam_ids; + std::stringstream ss(*rfsimu_params[beam_ids_param_index].strptr); + std::string token; + while (std::getline(ss, token, ',')) { + beam_ids.push_back(std::stoi(token)); + } + beam_ctrl->rx.beams = beam_ids; + beam_ctrl->tx.beams = beam_ids; + } + + if (strncasecmp(rfsimulator->ip, "enb", 3) == 0 || strncasecmp(rfsimulator->ip, "server", 3) == 0) rfsimulator->role = SIMU_ROLE_SERVER; else rfsimulator->role = SIMU_ROLE_CLIENT; } -static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) { +static int rfsimu_set_beam(char *buff, int debug, telnet_printfunc_t prnt, void *arg) +{ + rfsimulator_state_t *t = (rfsimulator_state_t *)arg; + rfsim_beam_ctrl_t *beam_ctrl = t->beam_ctrl; + AssertFatal(beam_ctrl->enable_beams, "Beam simualtion is disabled, cannot set beams\n"); + uint64_t beam_map = strtoull(buff, NULL, 0); + std::lock_guard lock_tx(beam_ctrl->tx.mutex); + std::lock_guard lock_rx(beam_ctrl->rx.mutex); + beam_ctrl->rx.beams = beam_map_to_beams(beam_map); + beam_ctrl->tx.beams = beam_map_to_beams(beam_map); + prnt("Beam map set to 0x%lx\n", beam_map); + return CMDSTATUS_FOUND; +} + +static int rfsimu_set_beamids(char *buff, int debug, telnet_printfunc_t prnt, void *arg) +{ + rfsimulator_state_t *t = (rfsimulator_state_t *)arg; + rfsim_beam_ctrl_t *beam_ctrl = t->beam_ctrl; + AssertFatal(beam_ctrl->enable_beams, "Beam simualtion is disabled, cannot set beams\n"); + std::vector beam_ids; + std::stringstream ss(buff); + std::string token; + while (std::getline(ss, token, ',')) { + beam_ids.push_back(std::stoi(token)); + } + std::lock_guard lock_tx(beam_ctrl->tx.mutex); + std::lock_guard lock_rx(beam_ctrl->rx.mutex); + beam_ctrl->rx.beams = beam_ids; + beam_ctrl->tx.beams = beam_ids; + prnt("Beam ids set\n"); + return CMDSTATUS_FOUND; +} + +static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) +{ char *modelname = NULL; char *modeltype = NULL; rfsimulator_state_t *t = (rfsimulator_state_t *)arg; @@ -398,7 +651,7 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, if (b->conn_sock >= 0 && (strcmp(b->channel_model->model_name, modelname) == 0)) { channel_desc_t *newmodel = new_channel_desc_scm(t->tx_num_channels, t->rx_num_channels, - channelmod, + static_cast(channelmod), t->sample_rate, t->rx_freq, t->tx_bw, @@ -460,7 +713,7 @@ static int rfsimu_setdistance_cmd(char *buff, int debug, telnet_printfunc_t prnt rfsimulator_state_t *t = (rfsimulator_state_t *)arg; const double sample_rate = t->sample_rate; - const double c = 299792458; /* 3e8 */ + const double c = (double) SPEED_OF_LIGHT; const uint64_t new_offset = (double)distance * sample_rate / c; const double new_distance = (double)new_offset * c / sample_rate; @@ -473,7 +726,8 @@ static int rfsimu_setdistance_cmd(char *buff, int debug, telnet_printfunc_t prnt /* Set distance in rfsim and channel model, update channel and ringbuffer */ for (int i = 0; i < MAX_FD_RFSIMU; i++) { buffer_t *b = &t->buf[i]; - if (b->conn_sock <= 0 || b->channel_model == NULL || b->channel_model->model_name == NULL || strcmp(b->channel_model->model_name, modelname) != 0) { + if (b->conn_sock <= 0 || b->channel_model == NULL || b->channel_model->model_name == NULL + || strcmp(b->channel_model->model_name, modelname) != 0) { if (b->channel_model != NULL && b->channel_model->model_name != NULL) prnt(" %s: model %s unmodified\n", __func__, b->channel_model->model_name); continue; @@ -495,7 +749,7 @@ static int rfsimu_getdistance_cmd(char *buff, int debug, telnet_printfunc_t prnt rfsimulator_state_t *t = (rfsimulator_state_t *)arg; const double sample_rate = t->sample_rate; - const double c = 299792458; /* 3e8 */ + const double c = (double) SPEED_OF_LIGHT; for (int i = 0; i < MAX_FD_RFSIMU; i++) { buffer_t *b = &t->buf[i]; @@ -534,9 +788,9 @@ static int startServer(openair0_device *device) snprintf(port, sizeof(port), "%d", t->port); struct addrinfo hints = { + .ai_flags = AI_PASSIVE, .ai_family = AF_INET6, .ai_socktype = SOCK_STREAM, - .ai_flags = AI_PASSIVE, }; int s = getaddrinfo(NULL, port, &hints, &results); @@ -633,7 +887,7 @@ static int client_try_connect(const char *host, uint16_t port) static int startClient(openair0_device *device) { - rfsimulator_state_t *t = device->priv; + rfsimulator_state_t *t = static_cast(device->priv); t->role = SIMU_ROLE_CLIENT; int sock; @@ -675,9 +929,10 @@ static int startClient(openair0_device *device) static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp timestamp, - void **samplesVoid, + void ***samplesVoid, int nsamps, int nbAnt, + std::vector tx_beams, int flags) { mutexlock(t->Sockmutex); @@ -687,27 +942,24 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, buffer_t *b = &t->buf[i]; if (b->conn_sock >= 0) { - samplesBlockHeader_t header = {nsamps, nbAnt, timestamp}; - if (!nbAnt) - LOG_E(HW, "rfsimulator sending 0 tx antennas\n"); + samplesBlockHeader_t header = {(uint32_t)nsamps, (uint32_t)nbAnt, (uint64_t)timestamp, 0, 0, beams_to_beam_map(tx_beams)}; fullwrite(b->conn_sock, &header, sizeof(header), t); - if (nbAnt == 1) { - fullwrite(b->conn_sock, samplesVoid[0], sampleToByte(nsamps, nbAnt), t); - } else { - sample_t tmpSamples[nsamps][nbAnt]; + int num_beams = tx_beams.size(); + // Send beams in order of beam index. This is required for beam_map to work correctly on the receiver side. + std::vector indices(tx_beams.size()); + std::iota(indices.begin(), indices.end(), 0); + std::sort(indices.begin(), indices.end(), [&](size_t i, size_t j) { return tx_beams[i] < tx_beams[j]; }); + + AssertFatal(num_beams > 0, "Must set at least one bit in beam_map\n"); + for (int beam = 0; beam < num_beams; beam++) { for (int a = 0; a < nbAnt; a++) { - sample_t *in = (sample_t *)samplesVoid[a]; - for (int s = 0; s < nsamps; s++) - tmpSamples[s][a] = in[s]; + sample_t *in = (sample_t *)samplesVoid[indices[beam]][a]; + fullwrite(b->conn_sock, (void *)in, sampleToByte(nsamps, 1), t); } - fullwrite(b->conn_sock, (void *)tmpSamples, sampleToByte(nsamps, nbAnt), t); } } } - if (t->lastWroteTS != 0 && fabs((double)t->lastWroteTS - timestamp) > (double)CirSize) - LOG_W(HW, "Discontinuous TX gap too large Tx:%lu, %lu\n", t->lastWroteTS, timestamp); - if (t->lastWroteTS > timestamp) LOG_W(HW, "Not supported to send Tx out of order %lu, %lu\n", t->lastWroteTS, timestamp); @@ -726,23 +978,54 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, nsamps, timestamp, timestamp + nsamps, - signal_energy(samplesVoid[0], nsamps)); + signal_energy(static_cast(samplesVoid[0][0]), nsamps)); /* trace only first antenna */ - T(T_USRP_TX_ANT0, T_INT(timestamp), T_BUFFER(samplesVoid[0], sampleToByte(nsamps, 1))); + T(T_USRP_TX_ANT0, T_INT(timestamp), T_BUFFER(samplesVoid[0], (int)sampleToByte(nsamps, 1))); return nsamps; } -static int rfsimulator_write(openair0_device *device, - openair0_timestamp timestamp, - void **samplesVoid, - int nsamps, - int nbAnt, - int flags) +static int rfsimulator_write_beams(openair0_device *device, + openair0_timestamp timestamp, + void ***samplesVoid, + int nsamps, + int nbAnt, + int num_beams, + int flags) { timestamp -= device->openair0_cfg->command_line_sample_advance; - return rfsimulator_write_internal(device->priv, timestamp, samplesVoid, nsamps, nbAnt, flags); + int nsamps_initial = nsamps; + rfsimulator_state_t *t = static_cast(device->priv); + void *samples[num_beams][nbAnt]; + void **samples_ptr[num_beams]; + for (int beam = 0; beam < num_beams; beam++) { + samples_ptr[beam] = samples[beam]; + for (int aatx = 0; aatx < nbAnt; aatx++) { + samples[beam][aatx] = samplesVoid[beam][aatx]; + } + } + while (nsamps > 0) { + uint32_t nsamps_beam_map; + std::vector beams = get_beams(&t->beam_ctrl->tx, timestamp, nsamps, &nsamps_beam_map); + rfsimulator_write_internal(t, timestamp, samples_ptr, nsamps_beam_map, nbAnt, beams, flags); + for (int beam = 0; beam < num_beams; beam++) { + for (int aatx = 0; aatx < nbAnt; aatx++) { + char *ptr = (char *)samples_ptr[beam][aatx]; + samples_ptr[beam][aatx] = (void *)(ptr + nsamps_beam_map * sizeof(sample_t)); + } + } + timestamp += nsamps_beam_map; + nsamps -= nsamps_beam_map; + } + clear_beam_queue(&t->beam_ctrl->tx, timestamp + nsamps); + return nsamps_initial; +} + +static int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) +{ + void **tmp = buff; + return rfsimulator_write_beams(device, timestamp, &tmp, nsamps, cc, 1, flags); } static bool add_client(rfsimulator_state_t *t) @@ -772,7 +1055,7 @@ static bool add_client(rfsimulator_state_t *t) void *samplesVoid[t->tx_num_channels]; for (int i = 0; i < t->tx_num_channels; i++) samplesVoid[i] = (void *)&v; - samplesBlockHeader_t header = {1, t->tx_num_channels, t->lastWroteTS}; + samplesBlockHeader_t header = {1, (uint32_t)t->tx_num_channels, (uint64_t)t->lastWroteTS, 0, 0, 1}; fullwrite(conn_sock, &header, sizeof(header), t); fullwrite(conn_sock, samplesVoid, sampleToByte(1, t->tx_num_channels), t); @@ -784,69 +1067,121 @@ static bool add_client(rfsimulator_state_t *t) static void process_recv_header(rfsimulator_state_t *t, buffer_t *b, bool first_time) { - // check the header and start block transfer - if (b->remainToTransfer != 0) - return; - b->headerMode = false; // We got the header - + AssertFatal(b->th.nbAnt != 0, "Number of antennas not set\n"); + if (b->nbAnt != b->th.nbAnt) { + LOG_A(HW, "RFsim: Number of antennas changed from %d to %d\n", b->nbAnt, b->th.nbAnt); + b->nbAnt = b->th.nbAnt; + } if (first_time) { b->lastReceivedTS = b->th.timestamp; b->trashingPacket = true; } else { - if (b->lastReceivedTS < b->th.timestamp) { - // We have a transmission hole to fill, like TDD - // we create no signal samples up to the beginning of this reception + if (b->lastReceivedTS < (int64_t)b->th.timestamp) { int nbAnt = b->th.nbAnt; if (!nbAnt) LOG_E(HW, "rfsimulator receive 0 rx antennas\n"); - if (b->th.timestamp - b->lastReceivedTS < CirSize) { - // case we wrap at circular buffer end - for (uint64_t index = b->lastReceivedTS; index < b->th.timestamp; index++) { - for (int a = 0; a < nbAnt; a++) { - b->circularBuf[(index * nbAnt + a) % CirSize] = (c16_t){0}; - } - } - } else { - // case no circular buffer wrap - memset(b->circularBuf, 0, sampleToByte(CirSize, 1)); - } b->lastReceivedTS = b->th.timestamp; - } else if (b->lastReceivedTS > b->th.timestamp) { + } else if (b->lastReceivedTS > (int64_t)b->th.timestamp) { LOG_W(HW, "Received data in past: current is %lu, new reception: %lu!\n", b->lastReceivedTS, b->th.timestamp); b->trashingPacket = true; } - // verify the time gap is not too large - mutexlock(t->Sockmutex); - if (t->lastWroteTS != 0 && (fabs((double)t->lastWroteTS - b->lastReceivedTS) > (double)CirSize)) - LOG_W(HW, "UEsock(%d) Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->conn_sock, t->lastWroteTS, b->lastReceivedTS); - mutexunlock(t->Sockmutex); } - // move back the pointer to overwrite the header, we don't need it anymore - b->transferPtr = (char *)&b->circularBuf[(b->lastReceivedTS * b->th.nbAnt) % CirSize]; - // we now need to read the samples - b->remainToTransfer = sampleToByte(b->th.size, b->th.nbAnt); - if (!b->remainToTransfer) - b->headerMode = true; // We got a header with 0 antennas, no I/Q to read + + int num_beams = __builtin_popcountll(b->th.beam_map); + AssertFatal(b->th.beam_map == 1ULL || t->beam_ctrl->enable_beams == 1, + "The transmitter has enabled beam simulation while this receiver has not\n"); + size_t payload_sz = sampleToByte(b->th.size, b->th.nbAnt) * num_beams; + b->packet_ptr = static_cast(calloc_or_fail(1, payload_sz + sizeof(samplesBlockHeader_t))); + b->packet_ptr->header = b->th; + b->transferPtr = b->packet_ptr->payload; + b->remainToTransfer = payload_sz; return; } -static void process_recv(rfsimulator_state_t *t, buffer_t *b, bool first_time) +/** + * @brief Combines samples from received packets into a single buffer for the rx beam + * + * This function processes the received_packets queue and combines the transmitted beams + * into a single buffer for each antenna. It applies the appropriate gain and handles + * overlapping timestamps. + * + * + * @param t Pointer to the rfsimulator_state_t structure. + * @param received_packets Reference to the queue of rfsim_packet_t pointers representing received packets. + * @param start_timestamp The start timestamp for the combination process. + * @param num_aatx The number of antennas to process. + * @param num_samples The number of samples to process. + * @param rx_beam_id Receiver configured beam id for the timestamp + * @param samples Pointer to the output buffer where combined samples will be stored. + * @return A vector of vectors containing the combined samples for each antenna. + */ +static void combine_received_beams(rfsimulator_state_t *t, + std::queue &received_packets, + uint64_t start_timestamp, + int num_aatx, + size_t num_samples, + int rx_beam_id, + c16_t **samples) { - if (b->transferPtr == b->circularBufEnd) - b->transferPtr = (char *)b->circularBuf; + // Assume received_packets is ordered by timestamp + std::queue packets_copy = received_packets; + while (!packets_copy.empty()) { + rfsim_packet_t *pkt = packets_copy.front(); + if (pkt->header.timestamp + pkt->header.size <= start_timestamp) { + // This packet is before the start timestamp, discard it + packets_copy.pop(); + continue; + } + if (pkt->header.timestamp > start_timestamp + num_samples) { + // This packet is after the end of the buffer, stop processing + break; + } - if (!b->trashingPacket) { - b->lastReceivedTS = b->th.timestamp + b->th.size - byteToSample(b->remainToTransfer, b->th.nbAnt); - LOG_D(HW, "UEsock: %d Set b->lastReceivedTS %ld\n", b->conn_sock, b->lastReceivedTS); - } - - if (b->remainToTransfer == 0) { - LOG_D(HW, "UEsock: %d Completed block reception: %ld\n", b->conn_sock, b->lastReceivedTS); - b->headerMode = true; - b->transferPtr = (char *)&b->th; - b->remainToTransfer = sizeof(samplesBlockHeader_t); - b->trashingPacket = false; + // The beams transmitted in are ordered by beam index + std::vector tx_beams = beam_map_to_beams(pkt->header.beam_map); + for (uint beam = 0; beam < tx_beams.size(); beam++) { + float gain_dB = get_rx_gain_db(t, rx_beam_id, tx_beams[beam]); + float gain_linear = powf(10, gain_dB / 20.0); + uint64_t overlap_start = std::max(start_timestamp, pkt->header.timestamp); + uint64_t overlap_end = std::min(start_timestamp + num_samples, pkt->header.timestamp + pkt->header.size); + int write_start_idx = overlap_start - start_timestamp; + int write_end_idx = overlap_end - start_timestamp; + int read_start_idx = overlap_start - pkt->header.timestamp; + for (int aatx = 0; aatx < num_aatx; aatx++) { + c16_t *buffer = (c16_t *)pkt->payload; + c16_t *tx_ant_buffer_in = &buffer[(num_aatx * beam + aatx) * pkt->header.size + read_start_idx]; + if (beam == 0) { + // For the first beam, we can directly copy the samples + if (gain_dB == 0.0f) { + // If gain is 0 dB, we can use memcpy for efficiency + memcpy(&samples[aatx][write_start_idx], tx_ant_buffer_in, (write_end_idx - write_start_idx) * sizeof(c16_t)); + } else { + for (int s = write_start_idx; s < write_end_idx; s++) { + samples[aatx][s].r = tx_ant_buffer_in->r * gain_linear; + samples[aatx][s].i = tx_ant_buffer_in->i * gain_linear; + tx_ant_buffer_in++; + } + } + } else { + // For subsequent beams, we need to ensure we accumulate the samples + if (gain_dB == 0.0f) { + for (int s = write_start_idx; s < write_end_idx; s++) { + samples[aatx][s].r += tx_ant_buffer_in->r; + samples[aatx][s].i += tx_ant_buffer_in->i; + tx_ant_buffer_in++; + } + } else { + for (int s = write_start_idx; s < write_end_idx; s++) { + samples[aatx][s].r += tx_ant_buffer_in->r * gain_linear; + samples[aatx][s].i += tx_ant_buffer_in->i * gain_linear; + tx_ant_buffer_in++; + } + } + } + } + } + packets_copy.pop(); } } @@ -864,7 +1199,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, bool first_time) } for (int nbEv = 0; nbEv < nfds; ++nbEv) { - buffer_t *b = events[nbEv].data.ptr; + buffer_t *b = static_cast(events[nbEv].data.ptr); if (events[nbEv].events & EPOLLIN && b == NULL) { bool ret = add_client(t); @@ -878,19 +1213,12 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, bool first_time) } } - if (b->circularBuf == NULL) { + if (b->conn_sock == -1) { LOG_E(HW, "Received data on not connected socket %d\n", events[nbEv].data.fd); continue; } - ssize_t blockSz; - if (b->headerMode) - blockSz = b->remainToTransfer; - else - blockSz = - b->transferPtr + b->remainToTransfer <= b->circularBufEnd ? b->remainToTransfer : b->circularBufEnd - b->transferPtr; - - ssize_t sz = recv(b->conn_sock, b->transferPtr, blockSz, MSG_DONTWAIT); + ssize_t sz = recv(b->conn_sock, b->transferPtr, b->remainToTransfer, MSG_DONTWAIT); if (sz <= 0) { if (sz < 0 && errno != EAGAIN) LOG_E(HW, "recv() failed, errno(%d)\n", errno); @@ -899,17 +1227,142 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, bool first_time) LOG_D(HW, "Socket rcv %zd bytes\n", sz); b->remainToTransfer -= sz; b->transferPtr += sz; - if (b->headerMode) - process_recv_header(t, b, first_time); - else - process_recv(t, b, first_time); + if (b->remainToTransfer == 0) { + if (b->headerMode) + process_recv_header(t, b, first_time); + else { + LOG_D(HW, "UEsock: %d Completed block reception: %ld\n", b->conn_sock, b->lastReceivedTS); + b->headerMode = true; + b->transferPtr = (char *)&b->th; + b->remainToTransfer = sizeof(samplesBlockHeader_t); + + if (!b->trashingPacket) { + b->lastReceivedTS = b->th.timestamp + b->th.size; + LOG_D(HW, "UEsock: %d Set b->lastReceivedTS %ld\n", b->conn_sock, b->lastReceivedTS); + b->received_packets.emplace(b->packet_ptr); + } else { + free(b->packet_ptr); + } + b->packet_ptr = NULL; + b->trashingPacket = false; + } + } } return nfds > 0; } -static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) +static void rfsimulator_read_internal(rfsimulator_state_t *t, + c16_t **samples, + openair0_timestamp timestamp, + int nsamps, + int nbAnt, + int rx_beam_id, + bool is_first_beam) { - rfsimulator_state_t *t = device->priv; + cf_t temp_array[nbAnt][nsamps]; + bool channel_modelling = false; + // Add all input nodes signal in the output buffer + bool is_first_peer = true; + for (int sock = 0; sock < MAX_FD_RFSIMU; sock++) { + buffer_t *ptr = &t->buf[sock]; + + if (ptr->conn_sock != -1 && !ptr->received_packets.empty()) { + AssertFatal(ptr->nbAnt != 0, "Number of antennas not set\n"); + bool reGenerateChannel = false; + + // fixme: when do we regenerate + // it seems legacy behavior is: never in UL, each frame in DL + if (reGenerateChannel) + random_channel(ptr->channel_model, 0); + + if (ptr->channel_model != NULL) { // apply a channel model + if (!channel_modelling) { + memset(temp_array, 0, sizeof(temp_array)); + channel_modelling = true; + } + const uint64_t channel_offset = ptr->channel_model->channel_offset; + const uint64_t channel_length = ptr->channel_model->channel_length; + std::vector> ant_buffers(ptr->nbAnt, std::vector(nsamps + channel_length - 1, {0, 0})); + c16_t *input[ant_buffers.size()]; + for (uint aatx = 0; aatx < ant_buffers.size(); aatx++) { + input[aatx] = ant_buffers[aatx].data(); + } + + combine_received_beams(t, + ptr->received_packets, + timestamp - channel_offset - (channel_length - 1), + ptr->nbAnt, + nsamps + channel_length - 1, + rx_beam_id, + input); + + for (int aarx = 0; aarx < nbAnt; aarx++) { + rxAddInput(input, temp_array[aarx], aarx, ptr->channel_model, nsamps, timestamp); + } + } else { + if (is_first_beam && is_first_peer && (ptr->nbAnt == 1 || nbAnt == 1)) { + // optimization: The buffer is uninitialized so samples can be written directly in the buffer + combine_received_beams(t, ptr->received_packets, timestamp - t->chan_offset, 1, nsamps, rx_beam_id, samples); + } else { + std::vector> ant_buffers(ptr->nbAnt, std::vector(nsamps, {0, 0})); + c16_t *input[ant_buffers.size()]; + for (uint aatx = 0; aatx < ant_buffers.size(); aatx++) { + input[aatx] = ant_buffers[aatx].data(); + } + combine_received_beams(t, ptr->received_packets, timestamp - t->chan_offset, ptr->nbAnt, nsamps, rx_beam_id, input); + for (int aarx = 0; aarx < nbAnt; aarx++) { + double H_awgn_mimo_coeff[ant_buffers.size()]; + for (int aatx = 0; aatx < (int)ant_buffers.size(); aatx++) { + uint32_t ant_diff = std::abs(aatx - aarx); + H_awgn_mimo_coeff[aatx] = ant_diff ? (0.2 / ant_diff) : 1.0; + } + + for (uint aatx = 0; aatx < ant_buffers.size(); aatx++) { + for (int i = 0; i < nsamps; i++) { + samples[aarx][i].r += ant_buffers[aatx][i].r * H_awgn_mimo_coeff[aatx]; + samples[aarx][i].i += ant_buffers[aatx][i].i * H_awgn_mimo_coeff[aatx]; + } + } + } + } + } + } + is_first_peer = false; + } + + bool apply_global_noise = get_noise_power_dBFS() != INVALID_DBFS_VALUE; + if (apply_global_noise) { + if (!channel_modelling) { + memset(temp_array, 0, sizeof(temp_array)); + channel_modelling = true; + } + int16_t noise_power = (int16_t)(32767.0 / powf(10.0, .05 * -get_noise_power_dBFS())); + for (int a = 0; a < nbAnt; a++) { + for (int i = 0; i < nsamps; i++) { + temp_array[a][i].r += noise_power + gaussZiggurat(0.0, 1.0); + temp_array[a][i].i += noise_power * gaussZiggurat(0.0, 1.0); + } + } + } + + if (channel_modelling) { + for (int a = 0; a < nbAnt; a++) { + for (int i = 0; i < nsamps; i++) { + samples[a][i].r += lroundf(temp_array[a][i].r); + samples[a][i].i += lroundf(temp_array[a][i].i); + } + } + } +} + +static int rfsimulator_read_beams(openair0_device *device, + openair0_timestamp *ptimestamp, + void ***samplesVoid, + int nsamps, + int nbAnt, + int num_beams) +{ + rfsimulator_state_t *t = static_cast(device->priv); LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld, nbAnt %d\n", nsamps, @@ -921,7 +1374,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest int first_sock; for (first_sock = 0; first_sock < MAX_FD_RFSIMU; first_sock++) - if (t->buf[first_sock].circularBuf != NULL) + if (t->buf[first_sock].conn_sock != -1) break; if (first_sock == MAX_FD_RFSIMU) { @@ -930,8 +1383,9 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest LOG_I(HW, "No connected device, generating void samples...\n"); if (!flushInput(t, t->wait_timeout, false)) { - for (int x = 0; x < nbAnt; x++) - memset(samplesVoid[x], 0, sampleToByte(nsamps, 1)); + for (int beam = 0; beam < num_beams; beam++) + for (int x = 0; x < nbAnt; x++) + memset(samplesVoid[beam][x], 0, sampleToByte(nsamps, 1)); t->nextRxTstamp += nsamps; @@ -948,9 +1402,9 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest buffer_t *b = NULL; for (int sock = 0; sock < MAX_FD_RFSIMU; sock++) { b = &t->buf[sock]; - if (b->circularBuf && (t->nextRxTstamp + nsamps) > b->lastReceivedTS) { - have_to_wait = true; - break; + if (b->conn_sock != -1 && (t->nextRxTstamp + nsamps) > b->lastReceivedTS) { + have_to_wait = true; + break; } } @@ -968,92 +1422,42 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest int ret = clock_gettime(CLOCK_REALTIME, &start_time); AssertFatal(ret == 0, "clock_gettime() failed: errno %d, %s\n", errno, strerror(errno)); - // Clear the output buffer - for (int a = 0; a < nbAnt; a++) - memset(samplesVoid[a], 0, sampleToByte(nsamps, 1)); - cf_t temp_array[nbAnt][nsamps]; - bool apply_noise_per_channel = get_noise_power_dBFS() == INVALID_DBFS_VALUE; - int num_chanmod_channels = 0; - // Add all input nodes signal in the output buffer for (int sock = 0; sock < MAX_FD_RFSIMU; sock++) { buffer_t *ptr = &t->buf[sock]; - if (ptr->circularBuf && !ptr->trashingPacket) { - bool reGenerateChannel = false; - - // fixme: when do we regenerate - // it seems legacy behavior is: never in UL, each frame in DL - if (reGenerateChannel) - random_channel(ptr->channel_model, 0); - - if (t->poll_telnetcmdq) - t->poll_telnetcmdq(t->telnetcmd_qid, t); - - for (int a_rx = 0; a_rx < nbAnt; a_rx++) { // loop over number of Rx antennas - if (ptr->channel_model != NULL) { // apply a channel model - if (num_chanmod_channels == 0) { - memset(temp_array, 0, sizeof(temp_array)); - } - num_chanmod_channels++; - rxAddInput(ptr->circularBuf, - temp_array[a_rx], - a_rx, - ptr->channel_model, - nsamps, - t->nextRxTstamp, - CirSize, - apply_noise_per_channel); - } else { // no channel modeling - int nbAnt_tx = ptr->th.nbAnt; // number of Tx antennas - int firstIndex = (CirSize + t->nextRxTstamp - t->chan_offset) % CirSize; - sample_t *out = (sample_t *)samplesVoid[a_rx]; - if (nbAnt_tx == 1 && t->nb_cnx == 1) { // optimized for 1 Tx and 1 UE - sample_t *firstSample = (sample_t *)&(ptr->circularBuf[firstIndex]); - if (firstIndex + nsamps > CirSize) { - int tailSz = CirSize - firstIndex; - memcpy(out, firstSample, sampleToByte(tailSz, 1)); - memcpy(out + tailSz, &ptr->circularBuf[0], sampleToByte(nsamps - tailSz, 1)); - } else { - memcpy(out, firstSample, sampleToByte(nsamps, 1)); - } - } else { - // SIMD (with simde) optimization might be added here later - LOG_D(HW, "nbAnt_tx %d nbAnt %d\n", nbAnt_tx, nbAnt); - double H_awgn_mimo_coeff[nbAnt_tx]; - for (int a_tx = 0; a_tx < nbAnt_tx; a_tx++) { - uint32_t ant_diff = abs(a_tx - a_rx); - H_awgn_mimo_coeff[a_tx] = ant_diff ? (0.2 / ant_diff) : 1.0; - } - for (int i = 0; i < nsamps; i++) { // loop over nsamps - for (int a_tx = 0; a_tx < nbAnt_tx; a_tx++) { // sum up signals from nbAnt_tx antennas - out[i].r += (short)(ptr->circularBuf[((firstIndex + i) * nbAnt_tx + a_tx) % CirSize].r * H_awgn_mimo_coeff[a_tx]); - out[i].i += (short)(ptr->circularBuf[((firstIndex + i) * nbAnt_tx + a_tx) % CirSize].i * H_awgn_mimo_coeff[a_tx]); - } // end for a_tx - } // end for i (number of samps) - } // end of 1 tx antenna optimization - } // end of no channel modeling - } // end for a (number of rx antennas) + if (ptr->conn_sock != -1 && ptr->channel_model != NULL) { + update_channel_model(ptr->channel_model, t->nextRxTstamp); } } - if (apply_noise_per_channel && num_chanmod_channels > 0) { - // Noise is already applied through the channel model - for (int a = 0; a < nbAnt; a++) { - sample_t *out = (sample_t *)samplesVoid[a]; - for (int i = 0; i < nsamps; i++) { - out[i].r += lroundf(temp_array[a][i].r); - out[i].i += lroundf(temp_array[a][i].i); - } + + if (t->poll_telnetcmdq) + t->poll_telnetcmdq(t->telnetcmd_qid, t); + + // Clear the output buffer + for (int beam = 0; beam < num_beams; beam++) + for (int a = 0; a < nbAnt; a++) + memset(samplesVoid[beam][a], 0, sampleToByte(nsamps, 1)); + + openair0_timestamp timestamp = t->nextRxTstamp; + int nsamps_to_process = nsamps; + while (nsamps_to_process > 0) { + uint32_t nsamps_beam_map; + std::vector rx_beams = get_beams(&t->beam_ctrl->tx, timestamp, nsamps_to_process, &nsamps_beam_map); + if ((int)rx_beams.size() != num_beams) { + LOG_D(HW, + "Number of beams does not match application request num_beams %d, beam_map beams %lu\n", + num_beams, + rx_beams.size()); } - } else if (num_chanmod_channels > 0) { - // Apply noise from global setting - int16_t noise_power = (int16_t)(32767.0 / powf(10.0, .05 * -get_noise_power_dBFS())); - for (int a = 0; a < nbAnt; a++) { - sample_t *out = (sample_t *)samplesVoid[a]; - for (int i = 0; i < nsamps; i++) { - out[i].r += lroundf(temp_array[a][i].r + noise_power * gaussZiggurat(0.0, 1.0)); - out[i].i += lroundf(temp_array[a][i].i + noise_power * gaussZiggurat(0.0, 1.0)); + for (int beam = 0; beam < num_beams && beam < (int)rx_beams.size(); beam++) { + c16_t *samples_beam[nbAnt]; + for (int i = 0; i < nbAnt; i++) { + samples_beam[i] = (c16_t *)samplesVoid[beam][i] + timestamp - t->nextRxTstamp; } + rfsimulator_read_internal(t, samples_beam, timestamp, nsamps_beam_map, nbAnt, rx_beams[beam], beam == 0); } + timestamp += nsamps_beam_map; + nsamps_to_process -= nsamps_beam_map; } struct timespec end_time; @@ -1069,32 +1473,59 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest *ptimestamp = t->nextRxTstamp; // return the time of the first sample t->nextRxTstamp += nsamps; + clear_beam_queue(&t->beam_ctrl->rx, t->nextRxTstamp); LOG_D(HW, "Rx to upper layer: %d from %ld to %ld, energy in first antenna %d\n", nsamps, *ptimestamp, t->nextRxTstamp, - signal_energy(samplesVoid[0], nsamps)); + signal_energy(static_cast(samplesVoid[0][0]), nsamps)); /* trace only first antenna */ - T(T_USRP_RX_ANT0, T_INT(t->nextRxTstamp), T_BUFFER(samplesVoid[0], sampleToByte(nsamps, 1))); + T(T_USRP_RX_ANT0, T_INT(t->nextRxTstamp), T_BUFFER(samplesVoid[0], (int)sampleToByte(nsamps, 1))); + + for (int sock = 0; sock < MAX_FD_RFSIMU; sock++) { + buffer_t *ptr = &t->buf[sock]; + + if (ptr->conn_sock != -1 && !ptr->received_packets.empty()) { + openair0_timestamp timestamp_to_free = t->nextRxTstamp - 1; + if (ptr->channel_model) { + timestamp_to_free -= + (ptr->channel_model->channel_length - 1) + std::max(ptr->channel_model->channel_offset, t->chan_offset); + } else { + timestamp_to_free -= t->chan_offset; + } + clear_old_packets(ptr->received_packets, timestamp_to_free); + } + } return nsamps; } -static int rfsimulator_get_stats(openair0_device *device) { +static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) +{ + return rfsimulator_read_beams(device, ptimestamp, &samplesVoid, nsamps, nbAnt, 1); +} + +static int rfsimulator_get_stats(openair0_device *device) +{ return 0; } -static int rfsimulator_reset_stats(openair0_device *device) { +static int rfsimulator_reset_stats(openair0_device *device) +{ return 0; } -static void rfsimulator_end(openair0_device *device) { - rfsimulator_state_t *s = device->priv; +static void rfsimulator_end(openair0_device *device) +{ + rfsimulator_state_t *s = static_cast(device->priv); for (int i = 0; i < MAX_FD_RFSIMU; i++) { buffer_t *b = &s->buf[i]; if (b->conn_sock >= 0) removeCirBuf(s, b); } + clear_beam_queue(&s->beam_ctrl->tx, INT64_MAX); + clear_beam_queue(&s->beam_ctrl->rx, INT64_MAX); + delete s->beam_ctrl; close(s->epollfd); free(s); } @@ -1106,40 +1537,41 @@ static void stopServer(openair0_device *device) rfsimulator_end(device); } -static int rfsimulator_stop(openair0_device *device) { +static int rfsimulator_stop(openair0_device *device) +{ return 0; } -static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg) { - rfsimulator_state_t *s = device->priv; +static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg) +{ + rfsimulator_state_t *s = static_cast(device->priv); s->rx_freq = openair0_cfg->rx_freq[0]; return 0; } -static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { +static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) +{ return 0; } -static int rfsimulator_write_init(openair0_device *device) { +static int rfsimulator_write_init(openair0_device *device) +{ return 0; } -__attribute__((__visibility__("default"))) -int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { +extern "C" __attribute__((__visibility__("default"))) int device_init(openair0_device *device, openair0_config_t *openair0_cfg) +{ // to change the log level, use this on command line // --log_config.hw_log_level debug - rfsimulator_state_t *rfsimulator = calloc(sizeof(rfsimulator_state_t), 1); + rfsimulator_state_t *rfsimulator = static_cast(calloc(sizeof(rfsimulator_state_t), 1)); // initialize channel simulation rfsimulator->tx_num_channels = openair0_cfg->tx_num_channels; rfsimulator->rx_num_channels = openair0_cfg->rx_num_channels; rfsimulator->sample_rate = openair0_cfg->sample_rate; rfsimulator->rx_freq = openair0_cfg->rx_freq[0]; rfsimulator->tx_bw = openair0_cfg->tx_bw; + rfsimulator->beam_ctrl = new rfsim_beam_ctrl_t; rfsimulator_readconfig(rfsimulator); if (rfsimulator->prop_delay_ms > 0.0) rfsimulator->chan_offset = ceil(rfsimulator->sample_rate * rfsimulator->prop_delay_ms / 1000); if (rfsimulator->chan_offset != 0) { - if (CirSize < minCirSize + rfsimulator->chan_offset) { - CirSize = minCirSize + rfsimulator->chan_offset; - LOG_I(HW, "CirSize = %lu\n", CirSize); - } rfsimulator->prop_delay_ms = rfsimulator->chan_offset * 1000 / rfsimulator->sample_rate; LOG_I(HW, "propagation delay %f ms, %lu samples\n", rfsimulator->prop_delay_ms, rfsimulator->chan_offset); } @@ -1157,12 +1589,18 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->trx_set_gains_func = rfsimulator_set_gains; device->trx_write_func = rfsimulator_write; device->trx_read_func = rfsimulator_read; + if (rfsimulator->beam_ctrl->enable_beams) { + device->trx_write_beams_func = rfsimulator_write_beams; + device->trx_read_beams_func = rfsimulator_read_beams; + } /* let's pretend to be a b2x0 */ device->type = RFSIMULATOR; openair0_cfg[0].rx_gain[0] = 0; device->openair0_cfg = &openair0_cfg[0]; device->priv = rfsimulator; device->trx_write_init = rfsimulator_write_init; + device->trx_set_beams = rfsimulator_set_beams; + device->trx_set_beams2 = rfsimulator_set_beams_vector; for (int i = 0; i < MAX_FD_RFSIMU; i++) rfsimulator->buf[i].conn_sock = -1; @@ -1170,7 +1608,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1, "epoll_create1() failed, errno(%d)", errno); // we need to call randominit() for telnet server (use gaussdouble=>uniformrand) - randominit(0); + randominit(); set_taus_seed(0); /* look for telnet server, if it is loaded, add the channel modeling commands to it */ add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); diff --git a/radio/rfsimulator/stored_node.c b/radio/rfsimulator/stored_node.c index 51db5bfea1..5792304671 100644 --- a/radio/rfsimulator/stored_node.c +++ b/radio/rfsimulator/stored_node.c @@ -177,6 +177,7 @@ int main(int argc, char *argv[]) { timestamp+=blockSize; header.option_value=0; header.option_flag=0; + header.beam_map = 1; } else { AssertFatal(read(fd,&header,sizeof(header)), ""); } diff --git a/radio/vrtsim/vrtsim.c b/radio/vrtsim/vrtsim.c index 9e678a5305..38dea17d76 100644 --- a/radio/vrtsim/vrtsim.c +++ b/radio/vrtsim/vrtsim.c @@ -54,7 +54,7 @@ typedef enum { ROLE_SERVER = 1, ROLE_CLIENT } role; #define MAX_NUM_ANTENNAS_TX 4 -#define MAX_CHANNEL_LENGTH (1 << 20) +#define SAVED_SAMPLES_LEN 256 #define ROLE_CLIENT_STRING "client" #define ROLE_SERVER_STRING "server" @@ -125,9 +125,6 @@ typedef struct { int client_num_rx_antennas; } vrtsim_state_t; -// Sample history for channel impulse response -static c16_t saved_samples[MAX_NUM_ANTENNAS_TX][MAX_CHANNEL_LENGTH] __attribute__((aligned(32))) = {0}; - static void histogram_add(histogram_t *histogram, double diff) { histogram->num_samples++; @@ -375,6 +372,9 @@ typedef struct { int nbAnt; int flags; int aarx; + int batch_size; + int num_batches; + c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN]; } channel_modelling_args_t; static void perform_channel_modelling(void *arg) @@ -417,49 +417,55 @@ static void perform_channel_modelling(void *arg) } } - for (int aatx = 0; aatx < nb_tx_ant; aatx++) { - c16_t *previous_samples = saved_samples[aatx]; - for (int i = 0; i < nsamps; i++) { - cf_t *impulse_response = channel_impulse_response_p[aatx]; - for (int l = 0; l < channel_desc->channel_length; l++) { - int idx = i - l; - // TODO: Use AVX2 for this - c16_t tx_input = idx >= 0 ? input_samples[aatx][idx] - : previous_samples[(channel_modelling_args->timestamp + i + idx) % MAX_CHANNEL_LENGTH]; - samples[i].r += tx_input.r * impulse_response[l].r - tx_input.i * impulse_response[l].i; - samples[i].i += tx_input.i * impulse_response[l].r + tx_input.r * impulse_response[l].i; + for (int batch_index = 0; batch_index < channel_modelling_args->num_batches; batch_index++) { + int start_sample = batch_index * channel_modelling_args->batch_size; + int num_samples = min(channel_modelling_args->batch_size, nsamps - start_sample); + if (start_sample >= nsamps) { + break; + } + for (int aatx = 0; aatx < nb_tx_ant; aatx++) { + for (int i = start_sample; i < start_sample + num_samples; i++) { + cf_t *impulse_response = channel_impulse_response_p[aatx]; + for (int l = 0; l < channel_desc->channel_length; l++) { + int idx = i - l; + // TODO: Use AVX2 for this + c16_t tx_input = idx >= 0 ? input_samples[aatx][idx] + : channel_modelling_args->saved_samples[aatx][SAVED_SAMPLES_LEN + idx]; + samples[i].r += tx_input.r * impulse_response[l].r - tx_input.i * impulse_response[l].i; + samples[i].i += tx_input.i * impulse_response[l].r + tx_input.r * impulse_response[l].i; + } } } - } - // Convert to c16_t - c16_t samples_out[aligned_nsamps] __attribute__((aligned(64))); -#if defined(__AVX512F__) - for (int i = 0; i < aligned_nsamps / 8; i++) { - simde__m512 *in = (simde__m512 *)&samples[i * 8]; - simde__m256i *out = (simde__m256i *)&samples_out[i * 8]; - *out = simde_mm512_cvtsepi32_epi16(simde_mm512_cvtps_epi32(*in)); - } -#elif defined(__AVX2__) - for (int i = 0; i < aligned_nsamps / 4; i++) { - simde__m256 *in = (simde__m256 *)&samples[i * 4]; - simde__m128i *out = (simde__m128i *)&samples_out[i * 4]; - *out = simde_mm256_cvtsepi32_epi16(simde_mm256_cvtps_epi32(*in)); - } -#else - for (int i = 0; i < nsamps; i++) { - samples_out[i].r = lroundf(samples[i].r); - samples_out[i].i = lroundf(samples[i].i); - } -#endif + // Convert to c16_t + c16_t samples_out[aligned_nsamps] __attribute__((aligned(64))); + #if defined(__AVX512F__) + for (int i = 0; i < aligned_nsamps / 8; i++) { + simde__m512 *in = (simde__m512 *)&samples[i * 8]; + simde__m256i *out = (simde__m256i *)&samples_out[i * 8]; + *out = simde_mm512_cvtsepi32_epi16(simde_mm512_cvtps_epi32(*in)); + } + #elif defined(__AVX2__) + for (int i = 0; i < aligned_nsamps / 4; i++) { + simde__m256 *in = (simde__m256 *)&samples[i * 4]; + simde__m128i *out = (simde__m128i *)&samples_out[i * 4]; + *out = simde_mm256_cvtsepi32_epi16(simde_mm256_cvtps_epi32(*in)); + } + #else + for (int i = 0; i < nsamps; i++) { + samples_out[i].r = lroundf(samples[i].r); + samples_out[i].i = lroundf(samples[i].i); + } + #endif - vrtsim_write_internal(channel_modelling_args->vrtsim_state, - channel_modelling_args->timestamp, - samples_out, - channel_modelling_args->nsamps, - aarx, - channel_modelling_args->flags, - aarx); + vrtsim_write_internal(channel_modelling_args->vrtsim_state, + channel_modelling_args->timestamp, + samples_out, + channel_modelling_args->nsamps, + aarx, + channel_modelling_args->flags, + aarx); + } } static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state, @@ -469,7 +475,13 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state, int nbAnt, int flags) { - AssertFatal(nbAnt < MAX_NUM_ANTENNAS_TX, "Number of antennas %d exceeds maximum %d\n", nbAnt, MAX_NUM_ANTENNAS_TX); + // Sample history for channel impulse response + static c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN] __attribute__((aligned(32))) = {0}; + // Indicates what samples are saves in saved_samples + static openair0_timestamp last_timestamp = 0; + const int batch_size = 4096; + + AssertFatal(nbAnt <= MAX_NUM_ANTENNAS_TX, "Number of antennas %d exceeds maximum %d\n", nbAnt, MAX_NUM_ANTENNAS_TX); for (int aarx = 0; aarx < vrtsim_state->peer_info.num_rx_antennas; aarx++) { notifiedFIFO_elt_t *task = newNotifiedFIFO_elt(sizeof(channel_modelling_args_t), 0, NULL, perform_channel_modelling); channel_modelling_args_t *args = (channel_modelling_args_t *)NotifiedFifoData(task); @@ -479,28 +491,45 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state, args->nbAnt = nbAnt; args->flags = flags; args->aarx = aarx; + args->batch_size = batch_size; + args->num_batches = (nsamps + batch_size - 1) / batch_size; for (int i = 0; i < nbAnt; i++) { args->samples[i] = samplesVoid[i]; } + + // Fill in saved_samples + size_t gap_samples = timestamp - last_timestamp; + if (gap_samples > 0) { + size_t gap_samples_needed = min(SAVED_SAMPLES_LEN, gap_samples); + for (int aatx = 0; aatx < nbAnt; aatx++) { + memset(&args->saved_samples[aatx][SAVED_SAMPLES_LEN - gap_samples_needed], 0, sizeof(c16_t) * gap_samples_needed); + if (gap_samples < SAVED_SAMPLES_LEN) { + size_t samples_from_saved = SAVED_SAMPLES_LEN - gap_samples_needed; + memcpy(&args->saved_samples[aatx][0], &saved_samples[aatx][SAVED_SAMPLES_LEN - samples_from_saved], sizeof(c16_t) * samples_from_saved); + } + } + } else { + for (int aatx = 0; aatx < nbAnt; aatx++) + memcpy(&args->saved_samples[aatx][0], saved_samples[aatx], sizeof(c16_t) * SAVED_SAMPLES_LEN); + } + memcpy(args->saved_samples, saved_samples, sizeof(saved_samples)); pushNotifiedFIFO(&vrtsim_state->channel_modelling_actors[aarx].fifo, task); } - int start_index = timestamp % MAX_CHANNEL_LENGTH; - int end_index = min(start_index + nsamps, MAX_CHANNEL_LENGTH); - int cp_nsamps = end_index - start_index; - for (int aatx = 0; aatx < nbAnt; aatx++) { - c16_t *samples = (c16_t *)samplesVoid[aatx]; - memcpy(&saved_samples[aatx][start_index], &samples[0], sizeof(c16_t) * cp_nsamps); - } - if (end_index < start_index + nsamps) { - // wrap around condition, write at beginning of buffer - cp_nsamps = nsamps - cp_nsamps; // remaining samples - start_index = 0; + // Save samples for next round + if (nsamps < SAVED_SAMPLES_LEN) { for (int aatx = 0; aatx < nbAnt; aatx++) { - c16_t *samples = (c16_t *)samplesVoid[aatx]; - memcpy(&saved_samples[aatx][start_index], &samples[0], sizeof(c16_t) * cp_nsamps); + memmove(&saved_samples[aatx][0], &saved_samples[aatx][nsamps], sizeof(c16_t) * (SAVED_SAMPLES_LEN - nsamps)); + memcpy(&saved_samples[aatx][SAVED_SAMPLES_LEN - nsamps], samplesVoid[aatx], sizeof(c16_t) * nsamps); + } + } else { + for (int aatx = 0; aatx < nbAnt; aatx++) { + c16_t* samples = (c16_t*)samplesVoid[aatx]; + memcpy(saved_samples[aatx], &samples[nsamps - SAVED_SAMPLES_LEN], sizeof(c16_t) * (SAVED_SAMPLES_LEN)); } } + + last_timestamp = timestamp + nsamps; return nsamps; } @@ -519,6 +548,18 @@ static int vrtsim_write(openair0_device *device, openair0_timestamp timestamp, v : vrtsim_write_internal(vrtsim_state, timestamp, (c16_t *)samplesVoid[0], nsamps, 0, flags, 0); } +static int vrtsim_write_beams(openair0_device *device, + openair0_timestamp timestamp, + void ***buff, + int nsamps, + int nb_antennas_tx, + int num_beams, + int flags) +{ + vrtsim_write(device, timestamp, (void **)buff[0], nsamps, nb_antennas_tx, flags); + return nsamps; +} + static int vrtsim_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { vrtsim_state_t *vrtsim_state = (vrtsim_state_t *)device->priv; @@ -628,8 +669,19 @@ static int vrtsim_set_freq(openair0_device *device, openair0_config_t *openair0_ return 0; } +static int vrtsim_set_beams(openair0_device *device, uint64_t beam_map, openair0_timestamp timestamp) +{ + return 0; +} + +static int vrtsim_set_beams2(openair0_device *device, int *beam_ids, int num_beams, openair0_timestamp timestamp) +{ + return 0; +} + __attribute__((__visibility__("default"))) int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { + randominit(); vrtsim_state_t *vrtsim_state = calloc_or_fail(1, sizeof(vrtsim_state_t)); vrtsim_readconfig(vrtsim_state); LOG_I(HW, @@ -643,6 +695,9 @@ __attribute__((__visibility__("default"))) int device_init(openair0_device *devi device->trx_set_gains_func = vrtsim_stub2; device->trx_write_func = vrtsim_write; device->trx_read_func = vrtsim_read; + device->trx_write_beams_func = vrtsim_write_beams; + device->trx_set_beams = vrtsim_set_beams; + device->trx_set_beams2 = vrtsim_set_beams2; device->type = RFSIMULATOR; device->openair0_cfg = &openair0_cfg[0]; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band66.25prb.rfsim.pci0.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band66.25prb.rfsim.pci0.conf index 1d3e0e70d0..8c200c72fd 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band66.25prb.rfsim.pci0.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band66.25prb.rfsim.pci0.conf @@ -19,7 +19,6 @@ gNBs = ////////// Physical parameters: min_rxtxtime = 4; - sib1_tda = 15; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band66.25prb.rfsim.pci1.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band66.25prb.rfsim.pci1.conf index cdcd1a59fd..f87cc2bb8c 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band66.25prb.rfsim.pci1.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band66.25prb.rfsim.pci1.conf @@ -19,7 +19,6 @@ gNBs = ////////// Physical parameters: min_rxtxtime = 4; - sib1_tda = 15; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.4x4-benetel650.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.4x4-benetel650.conf index 7a6becbd8c..1652758e4e 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.4x4-benetel650.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.4x4-benetel650.conf @@ -23,7 +23,6 @@ gNBs = pusch_AntennaPorts = 4; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; force_UL256qam_off = 1; # maxMIMO_layers = 2; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.4x4-das-benetel650_650.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.4x4-das-benetel650_650.conf new file mode 100644 index 0000000000..1650f8a4e1 --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.4x4-das-benetel650_650.conf @@ -0,0 +1,268 @@ +Active_gNBs = ( "gNB-OAI-DU"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_DU_ID = 0xe00; + gNB_name = "gNB-OAI-DU"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ( { sst = 1; }); }); + + nr_cellid = 1; + + ////////// Physical parameters: + + pdsch_AntennaPorts_XP = 2; + pdsch_AntennaPorts_N1 = 2; + pusch_AntennaPorts = 4; + do_CSIRS = 1; + do_SRS = 0; + force_UL256qam_off = 1; + maxMIMO_layers = 2; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + # n_TimingAdvanceOffset = 0; +# downlinkConfigCommon + #frequencyInfoDL + # center frequency = 3950.4 MHz + # selected SSB frequency = 3950.4 MHz + absoluteFrequencySSB = 663360; + dl_frequencyBand = 77; + # frequency point A = 3901.26 MHz + dl_absoluteFrequencyPointA = 660084; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 273; + #initialDownlinkBWP + #genericParameters + initialDLBWPlocationAndBandwidth = 1099; #38.101-1 Table 5.3.2-1 + # +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 11; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 77; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 273; + pMax = 23; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 1099; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 152; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 0; + preambleReceivedTargetPower = -100; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 8; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 3; +#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; +#one (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, + +# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB + msg3_DeltaPreamble = 2; + p0_NominalWithGrant = -96; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 0; + p0_nominal = -96; + + ssb_PositionsInBurst_Bitmap = 0x1; + +# 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 = 5; + nrofDownlinkSlots = 3; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 1; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + } +); + + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "f1"; + local_n_address = "172.21.16.51"; + remote_n_address = "172.21.6.90"; + local_n_portd = 2153; + remote_n_portd = 2153; + pusch_TargetSNRx10 = 120; + pucch_TargetSNRx10 = 200; + dl_bler_target_upper = .35; + dl_bler_target_lower = .15; + ul_bler_target_upper = .35; + ul_bler_target_lower = .15; + pusch_FailureThres = 100; + ul_max_mcs = 28; + min_grant_prb = 1; + set_analog_beamforming = 1; + beam_duration = 1; + beams_per_period = 2; +} +); + +L1s = ( +{ + enable_das = 1; + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 100; + pucch0_dtx_threshold = 80; + pusch_dtx_threshold = 10; + max_ldpc_iterations = 10; + tx_amp_backoff_dB = 12; # needs to match O-RU configuration + L1_rx_thread_core = 8; + L1_tx_thread_core = 10; # relevant after merge of l1_tx_thread + phase_compensation = 0; # needs to match O-RU configuration +} +); + +RUs = ( +{ + local_rf = "no"; + nb_tx = 4; + nb_rx = 4; + att_tx = 0; + att_rx = 0; + bands = [77]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + sf_extension = 0; + eNB_instances = [0]; + ru_thread_core = 9; + sl_ahead = 10; + tr_preference = "raw_if4p5"; # important: activate FHI7.2 + do_precoding = 0; # needs to match O-RU configuration +} +); + +log_config : +{ + global_log_level = "info"; + hw_log_level = "info"; + phy_log_level = "info"; + mac_log_level = "info"; + rlc_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; + ngap_log_level = "info"; + f1ap_log_level = "info"; +}; + +fhi_72 = { + dpdk_devices = ("0000:01:01.0", "0000:01:01.1", "0000:01:01.2", "0000:01:01.3"); # two VFs can be used as well + system_core = 0; + io_core = 1; + worker_cores = (2); + ru_addr = ("8c:1f:64:d1:10:46","8c:1f:64:d1:10:46","8c:1f:64:d1:10:43","8c:1f:64:d1:10:43"); # if two VFs, set two RU MAC addresses (one per RU) + mtu = 9600; + fh_config = ( +# RAN650 #1 + { + T1a_cp_dl = (419, 470); + T1a_cp_ul = (285, 336); + T1a_up = (294, 345); + Ta4 = (0, 200); + ru_config = { + iq_width = 9; + iq_width_prach = 9; + }; + }, +# RAN650 #2 + { + T1a_cp_dl = (419, 470); + T1a_cp_ul = (285, 336); + T1a_up = (294, 345); + Ta4 = (0, 200); + ru_config = { + iq_width = 9; + iq_width_prach = 9; + }; + }); +}; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf index 3dd36be9c7..eee6f875c9 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf @@ -23,7 +23,6 @@ gNBs = pusch_AntennaPorts = 8; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; force_UL256qam_off = 1; maxMIMO_layers = 2; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650.conf index 18829188e3..fdad2726c2 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650.conf @@ -23,7 +23,6 @@ gNBs = pusch_AntennaPorts = 8; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; force_UL256qam_off = 1; maxMIMO_layers = 2; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.106prb.nfapi.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.106prb.nfapi.conf index aea3176456..467873a36f 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.106prb.nfapi.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.106prb.nfapi.conf @@ -22,7 +22,6 @@ gNBs = pusch_AntennaPorts = 1; min_rxtxtime = 6; enable_sdap = 0; - #sib1_tda = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf index a6ca5decbe..10caa403d3 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf @@ -16,7 +16,6 @@ gNBs = ////////// Physical parameters: - sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; cu_sibs = [2]; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf index c811f0d64e..1684a375d0 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf @@ -16,7 +16,6 @@ gNBs = ////////// Physical parameters: - sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; cu_sibs = [2]; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf index 3a472ff7a2..c20188594d 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf @@ -16,7 +16,6 @@ gNBs = ////////// Physical parameters: - sib1_tda = 5; min_rxtxtime = 6; disable_harq = 1; cu_sibs = [2]; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.u3.32prb.usrpx410.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.u3.32prb.usrpx410.conf index 933cddfcb9..0c949fdccb 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.u3.32prb.usrpx410.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band257.u3.32prb.usrpx410.conf @@ -21,7 +21,6 @@ gNBs = pusch_AntennaPorts = 1; do_CSIRS = 1; do_SRS = 1; - sib1_tda = 15; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf index a02394b5b2..bb5263aa9a 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.52PRB.usrpb210.conf @@ -22,7 +22,6 @@ gNBs = do_CSIRS = 1; do_SRS = 1; - sib1_tda = 15; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf index 6b9b104bc0..f17e695e8a 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf @@ -32,7 +32,6 @@ gNBs = ////////// Physical parameters: - sib1_tda = 5; min_rxtxtime = 6; # disable_harq = 1; # num_dlharq = 32; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf index 560b33b0e9..d5b0559f0c 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf @@ -32,7 +32,6 @@ gNBs = ////////// Physical parameters: - sib1_tda = 5; min_rxtxtime = 6; # disable_harq = 1; # num_dlharq = 32; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.u0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.u0.25prb.rfsim.conf index 9458c2b272..428b6cb27c 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.u0.25prb.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.u0.25prb.rfsim.conf @@ -17,7 +17,6 @@ gNBs = ////////// Physical parameters: - sib1_tda = 5; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.106prb.fhi72.4x4-vvdn.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.106prb.fhi72.4x4-vvdn.conf index 753670a9eb..f7f8390b33 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.106prb.fhi72.4x4-vvdn.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.106prb.fhi72.4x4-vvdn.conf @@ -23,7 +23,6 @@ gNBs = pusch_AntennaPorts = 4; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.2x2-vvdn.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.2x2-vvdn.conf index 38580730f2..d68e67c96f 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.2x2-vvdn.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.2x2-vvdn.conf @@ -21,7 +21,6 @@ gNBs = pusch_AntennaPorts = 2; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf index d55bc6dbda..7e13bf7dec 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.273prb.fhi72.4x4-vvdn.conf @@ -23,7 +23,6 @@ gNBs = pusch_AntennaPorts = 4; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x2-benetel550.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x2-benetel550.conf index 75fe0e6fdd..715dcda78c 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x2-benetel550.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x2-benetel550.conf @@ -21,7 +21,6 @@ gNBs = pusch_AntennaPorts = 2; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; # force_UL256qam_off = 1; servingCellConfigCommon = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf index ed996cac27..241ca9f23a 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf @@ -23,7 +23,6 @@ gNBs = pusch_AntennaPorts = 4; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; # force_UL256qam_off = 1; servingCellConfigCommon = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf index d8ca02a3be..2788e7f5f5 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550.conf @@ -23,7 +23,6 @@ gNBs = pusch_AntennaPorts = 4; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; # force_UL256qam_off = 1; servingCellConfigCommon = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-liteon.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-liteon.conf index 09b40913f9..f5f656202d 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-liteon.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-liteon.conf @@ -23,7 +23,6 @@ gNBs = pusch_AntennaPorts = 4; do_CSIRS = 1; do_SRS = 0; - sib1_tda = 15; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-metanoia.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-metanoia.conf index 13617fb578..322d61b2b3 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-metanoia.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-metanoia.conf @@ -21,7 +21,6 @@ gNBs = do_CSIRS = 1; do_SRS = 0; force_UL256qam_off = 1; - # sib1_tda = 15; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf index 1398020417..63c63bd80e 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf @@ -17,7 +17,6 @@ gNBs = ////////// Physical parameters: - sib1_tda = 15; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/neighbour-config-rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/neighbour-config-rfsim.conf index cff9d2b293..641fbb2003 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/neighbour-config-rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/neighbour-config-rfsim.conf @@ -57,21 +57,21 @@ nr_measurement_configuration = { A2 = { enable = 1; threshold = 60; - timeToTrigger = 1; + time_to_trigger = 1; }; A3 = ( { - cell_id = 720898; # neighbour of gNB 0xe00 + physCellId = 1; # neighbour of gNB 0xe00 offset = 10; hysteresis = 0; - timeToTrigger = 1; + time_to_trigger = 1; }, { - cell_id = 12345678; # neighbour of gNB 0xb00 + physCellId = 0; # neighbour of gNB 0xb00 offset = 5; hysteresis = 1; - timeToTrigger = 2; + time_to_trigger = 2; } ); };
Relative Time (s)Test IdTest IndexTest DescTest OptionsTest Status
' + format(currentTime / 1000, '.1f') + '' + self.testCase_id + '' + self.testCaseIdx + '' + self.desc + '' + str(options) + '
' + format(currentTime / 1000, '.1f') + '' + self.testCase_id + '' + self.testCaseIdx + '' + self.desc + '' + str(options) + '